Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 3068

kernel-2.6.18-238.el5.src.rpm

From: Bob Picco <bpicco@redhat.com>
Date: Wed, 8 Dec 2010 14:50:57 -0500
Subject: [net] s2io: fix netdev initialization failure
Message-id: <20101208145320.3971.98673.sendpatchset@localhost.localdomain>
Patchwork-id: 29981
O-Subject: [RHEL5.6 PATCH V2] BZ654948 s2io netdev initialization failure
Bugzilla: 654948
RH-Acked-by: Stefan Assmann <sassmann@redhat.com>
RH-Acked-by: Michal Schmidt <mschmidt@redhat.com>

bz#654948

V2
This is a small change and only compile tested. I discovered
why Michal saw chattiness on Altix and the bz's reporter
log is chatty too. All debug information is being logged for the driver.
The upstream commit was picked up in R6 with commit
	ff8502c96001b8a3e91eac6dd1d7f9fd55e4136c
.  I cherry-picked upstream commit
	git.kernel.org/linus/5447080cfa3c77154498dfbf225367ac85b4c2b5
. The small change can be seen in DBG_PRINT macro in s2io.h.

V1
Michal and I worked on this blocker. The issue manifested because
of R5 commit 144e94883f6a158e7eca29e6e1bed9acf3f03ed2. Basically a network
driver requiring more than 64Kb of private data for netdev allocation will
fail to initialize. So the allocation required for a large netdev private
allocation can require multiple memory allocations for device initialization.

Tested by reporter. Michal attempted to test locally but there are
unresolved issues with: altix350-01.rhts.eng.rdu.redhat.com.

Signed-off-by: Bob Picco <bpicco@redhat.com>

 drivers/net/s2io.c |   18 +++++++++++++-----
 drivers/net/s2io.h |    4 ++--
 2 files changed, 15 insertions(+), 7 deletions(-)

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 9473938..c020836 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -7802,6 +7802,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	u16 subid;
 	struct config_param *config;
 	struct mac_info *mac_control;
+	struct ring_info *rings;
 	int mode;
 	u8 dev_intr_type = intr_type;
 	u8 dev_multiq = 0;
@@ -7846,11 +7847,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 		dev = alloc_etherdev_mq(sizeof(struct s2io_nic), tx_fifo_num);
 	else
 		dev = alloc_etherdev(sizeof(struct s2io_nic));
-	if (dev == NULL) {
+
+	rings = kzalloc(sizeof (struct ring_info) * MAX_RX_RINGS, GFP_KERNEL);
+
+	if (dev == NULL || rings == NULL) {
 		DBG_PRINT(ERR_DBG, "Device allocation failed\n");
-		pci_disable_device(pdev);
-		pci_release_regions(pdev);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto nodev;
 	}
 
 	pci_set_master(pdev);
@@ -7891,6 +7894,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	 */
 	config = &sp->config;
 	mac_control = &sp->mac_control;
+	mac_control->rings = rings;
 
 	config->napi = napi;
 	config->tx_steering_type = tx_steering_type;
@@ -8320,10 +8324,13 @@ bar1_remap_failed:
 bar0_remap_failed:
 mem_alloc_failed:
 	free_shared_mem(sp);
+nodev:
 	pci_disable_device(pdev);
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
-	free_netdev(dev);
+	if (dev)
+		free_netdev(dev);
+	kfree(rings);
 
 	return ret;
 }
@@ -8364,6 +8371,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
 	iounmap(sp->bar1);
 	pci_release_regions(pdev);
 	pci_set_drvdata(pdev, NULL);
+	kfree(sp->mac_control.rings);
 	free_netdev(dev);
 	pci_disable_device(pdev);
 }
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 2fc3c87..75cbbc2 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -65,7 +65,7 @@ static int debug_level = ERR_DBG;
 
 /* DEBUG message print. */
 #define DBG_PRINT(dbg_level, fmt, args...) do {			\
-	if (dbg_level >= debug_level)				\
+	if (dbg_level <= debug_level)				\
 		pr_info(fmt, ##args);				\
 	} while (0)
 
@@ -808,7 +808,7 @@ struct mac_info {
 
 /* rx side stuff */
 	/* Ring specific structure */
-	struct ring_info rings[MAX_RX_RINGS];
+	struct ring_info *rings;
 
 	u16 rmac_pause_time;
 	u16 mc_pause_threshold_q0q3;