From patchwork Thu Oct 1 10:27:20 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Schmidt X-Patchwork-Id: 34666 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 7EF00B7BD0 for ; Thu, 1 Oct 2009 20:22:24 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756172AbZJAKWP (ORCPT ); Thu, 1 Oct 2009 06:22:15 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1756157AbZJAKWO (ORCPT ); Thu, 1 Oct 2009 06:22:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50319 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756071AbZJAKWO (ORCPT ); Thu, 1 Oct 2009 06:22:14 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n91AMISP017172; Thu, 1 Oct 2009 06:22:18 -0400 Received: from leela (vpn1-4-128.ams2.redhat.com [10.36.4.128]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id n91AMGbf010098; Thu, 1 Oct 2009 06:22:17 -0400 Date: Thu, 1 Oct 2009 12:27:20 +0200 From: Michal Schmidt To: Stephen Hemminger Cc: netdev@vger.kernel.org Subject: [PATCH] skge: use unique IRQ name Message-ID: <20091001122720.3822bdd3@leela> In-Reply-To: <20090922092826.5302225c@s6510> References: <20090922120127.14242.71353.stgit@localhost.localdomain> <20090922092826.5302225c@s6510> Organization: Red Hat Mime-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Most network drivers request their IRQ when the interface is activated. skge does it in ->probe() instead, because it can work with two-port cards where the two net_devices use the same IRQ. This works fine most of the time, except in some situations when the interface gets renamed. Consider this example: 1. modprobe skge The card is detected as eth0 and requests IRQ 17. Directory /proc/irq/17/eth0 is created. 2. There is an udev rule which says this interface should be called eth1, so udev renames eth0 -> eth1. 3. modprobe 8139too The Realtek card is detected as eth0. It will be using IRQ 17 too. 4. ip link set eth0 up Now 8139too requests IRQ 17. The result is: WARNING: at fs/proc/generic.c:590 proc_register ... proc_dir_entry '17/eth0' already registered ... And "ls /proc/irq/17" shows two subdirectories, both called eth0. Fix it by using a unique name for skge's IRQ, based on the PCI address. The naming from the example then looks like this: $ grep skge /proc/interrupts 17: 169 IO-APIC-fasteoi skge@0000:00:0a.0, eth0 irqbalance daemon will have to be taught to recognize "skge@" as an Ethernet interrupt. This will be a one-liner addition in classify.c. I will send a patch to irqbalance if this change is accepted. Signed-off-by: Michal Schmidt --- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: kernel/drivers/net/skge.c =================================================================== --- kernel.orig/drivers/net/skge.c +++ kernel/drivers/net/skge.c @@ -3895,6 +3895,7 @@ static int __devinit skge_probe(struct p struct net_device *dev, *dev1; struct skge_hw *hw; int err, using_dac = 0; + size_t irq_name_len; err = pci_enable_device(pdev); if (err) { @@ -3935,11 +3936,13 @@ static int __devinit skge_probe(struct p #endif err = -ENOMEM; - hw = kzalloc(sizeof(*hw), GFP_KERNEL); + irq_name_len = strlen(DRV_NAME) + strlen(dev_name(&pdev->dev)) + 2; + hw = kzalloc(sizeof(*hw) + irq_name_len, GFP_KERNEL); if (!hw) { dev_err(&pdev->dev, "cannot allocate hardware struct\n"); goto err_out_free_regions; } + sprintf(hw->irq_name, DRV_NAME "@%s", dev_name(&pdev->dev)); hw->pdev = pdev; spin_lock_init(&hw->hw_lock); @@ -3974,7 +3977,7 @@ static int __devinit skge_probe(struct p goto err_out_free_netdev; } - err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, dev->name, hw); + err = request_irq(pdev->irq, skge_intr, IRQF_SHARED, hw->irq_name, hw); if (err) { dev_err(&pdev->dev, "%s: cannot assign irq %d\n", dev->name, pdev->irq); Index: kernel/drivers/net/skge.h =================================================================== --- kernel.orig/drivers/net/skge.h +++ kernel/drivers/net/skge.h @@ -2423,6 +2423,8 @@ struct skge_hw { u16 phy_addr; spinlock_t phy_lock; struct tasklet_struct phy_task; + + char irq_name[0]; /* name for /proc/interrupts */ }; enum pause_control {