Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3180

kernel-2.6.18-194.11.1.el5.src.rpm

From: Hans-Joachim Picht <hpicht@redhat.com>
Date: Fri, 25 Apr 2008 15:08:06 +0200
Subject: [s390] qeth: avoid inconsistent lock state for inet6_dev
Message-id: 20080425130806.GD22728@redhat.com
O-Subject: [RHEL5 U3 PATCH 4/5] s390 - qeth: avoid inconsistent lock state for inet6_dev->lock
Bugzilla: 444077
RH-Acked-by: John W. Linville <linville@redhat.com>
RH-Acked-by: Pete Zaitcev <zaitcev@redhat.com>

Description
============

qeth recovery hang was observed, but other problems may have
been possible.

ipv6_regen_rndid in net/ipv6/addrconf.c makes use of
"write_lock_bh" for its inet6_dev->lock. It may run in
softirq-context. qeth makes use of "read_lock" for the same
inet_dev->lock. This can cause a deadlock.

The solution is to use read_lock_bh to get inet6_dev->lock.

Bugzilla
=========

BZ 444077
https://bugzilla.redhat.com/show_bug.cgi?id=444077

Upstream status of the patch:
=============================

Patch is contained in linux-2.6 as git commit
add3f2fa7a6cec16d35a95b9078e1ecc80a6f332

Test status:
============

The patch has been tested and fixes the problem.
The fix has been verified by the IBM test department.

Please ACK.

With best regards,

Hans

 drivers/s390/net/qeth_main.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index d3f119a..6d9ec25 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -5922,9 +5922,9 @@ qeth_add_vlan_mc6(struct qeth_card *card)
 		in_dev = in6_dev_get(vg->vlan_devices[i]);
 		if (!in_dev)
 			continue;
-		read_lock(&in_dev->lock);
+		read_lock_bh(&in_dev->lock);
 		qeth_add_mc6(card,in_dev);
-		read_unlock(&in_dev->lock);
+		read_unlock_bh(&in_dev->lock);
 		in6_dev_put(in_dev);
 	}
 #endif /* CONFIG_QETH_VLAN */
@@ -5941,10 +5941,10 @@ qeth_add_multicast_ipv6(struct qeth_card *card)
 	in6_dev = in6_dev_get(card->dev);
 	if (in6_dev == NULL)
 		return;
-	read_lock(&in6_dev->lock);
+	read_lock_bh(&in6_dev->lock);
 	qeth_add_mc6(card, in6_dev);
 	qeth_add_vlan_mc6(card);
-	read_unlock(&in6_dev->lock);
+	read_unlock_bh(&in6_dev->lock);
 	in6_dev_put(in6_dev);
 }
 #endif /* CONFIG_QETH_IPV6 */