Sophie

Sophie

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

kernel-2.6.18-238.el5.src.rpm

From: Scott Moser <smoser@redhat.com>
Subject: [PATCH RHEL5u1] [ppc] bz251370 kernel panic on DLPAR remove of eHEA 	logical port [repost]
Date: Thu, 16 Aug 2007 15:43:21 -0400 (EDT)
Bugzilla: 251370
Message-Id: <Pine.LNX.4.64.0708161457210.30310@squad5-lp1.lab.boston.redhat.com>
Changelog: [net] fix DLPAR remove of eHEA logical port


This is a repost of the same patch that I posted earlier, but with an
improved description and justification.

RHBZ#: 251370
------
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=251370

Description:
------------
On RHEL 5.1 beta1 during verification of DLPAR functions the following
2 problems were found:
 1. the driver is currently using hex values where the user space tool is
expecting decimal values.
 2.  eHEA driver and OpenFirmware service cause kernel panic when DLPAR is
  trying to remove a previously added eHEA logical port.

In (Open Firmware) of_device.c there is a function called
of_device_register.  This function is called by the eHEA driver. 
It adds a property to the of_device, and sets the properties name as:
   new_prop->name = "linux,device";

On device removal, of_node_release is called, which calls of_node_release,
which ends up doing a kfree on the static "linux,device" property. This
causes kernel panic.

The solution below simply does not call of_node_put on removal of the
device from the system.  This is a simple fix contained within the eHEA
driver so as to avoid negative affects on other drivers or the kernel.
The workaround has been fully tested by the driver team and they believe
it is the correct solution to make DLPAR function for RHEL 5u1.

This does cause a small memory leak on add and remove of a eHEA port.
This operation is rare, occuring only when a user removes a device from
the system.  Thus, there is only a minimal amount of memory lost even on
repeated inserts and removes.

Upstream Status:
----------------
This bug is fixed upstream.  The fix is in git commit
980ffd3258dbcdb011e929de5d658ec81febba8d [1].  I do believe that is the
correct fix, but it has not been tested when applied to RHEL5u1.  Because
it has a larger scope than the change described above we are hesitant to
suggest it now.

RHEL Version Found:
-------------------
2.6.18-39.el5

Test Status:
------------
To ensure cross-platform build, this code has been built with brew
--scratch against a 2.6.18-39.el5 kernel and is available at [5].

This build has been tested by Thomas Klein of IBM.  A full regression test
suite has been run on the built kernel and verification of hot plug add
and remove has been done.

--
[1] http://git.kernel.org/gitweb.cgi?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=980ffd3258dbcdb011e929de5d658ec81febba8d
[2] http://brewweb.devel.redhat.com/brew/taskinfo?taskID=917509
---
 drivers/net/ehea/ehea.h      |    2 +-
 drivers/net/ehea/ehea_main.c |    9 ++++-----
 2 files changed, 5 insertions(+), 6 deletions(-)
Index: b/drivers/net/ehea/ehea.h
===================================================================
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0058-01"
+#define DRV_VERSION	"EHEA_0058-03"
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
 	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
Index: b/drivers/net/ehea/ehea_main.c
===================================================================
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2393,7 +2393,7 @@ static ssize_t ehea_show_port_id(struct 
 				 struct device_attribute *attr, char *buf)
 {
 	struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
-	return sprintf(buf, "0x%X", port->logical_port_id);
+	return sprintf(buf, "%d", port->logical_port_id);
 }
 
 static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id,
@@ -2401,8 +2401,7 @@ static DEVICE_ATTR(log_port_id, S_IRUSR 
 
 static void __devinit logical_port_release(struct device *dev)
 {
-	struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev);
-	of_node_put(port->ofdev.node);
+	return;
 }
 
 static int ehea_driver_sysfs_add(struct device *dev,
@@ -2668,7 +2667,7 @@ static ssize_t ehea_probe_port(struct de
 
 	u32 logical_port_id;
 
-	sscanf(buf, "%X", &logical_port_id);
+	sscanf(buf, "%d", &logical_port_id);
 
 	port = ehea_get_port(adapter, logical_port_id);
 
@@ -2721,7 +2720,7 @@ static ssize_t ehea_remove_port(struct d
 	int i;
 	u32 logical_port_id;
 
-	sscanf(buf, "%X", &logical_port_id);
+	sscanf(buf, "%d", &logical_port_id);
 
 	port = ehea_get_port(adapter, logical_port_id);