diff options
author | Ursula Braun <braunu@de.ibm.com> | 2007-08-29 05:26:52 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-08-31 06:52:57 -0400 |
commit | d0a34f98d1da66a5b4e02171854e6c04c9916016 (patch) | |
tree | e56ea20b7a94744b9269a5c2a1b8327797bd8534 | |
parent | 3052246c815fe17ff3a9fcb5601c6688b523e5f5 (diff) |
qeth: ungrouping a device must not be interruptible
Problem:
A recovery thread must not be active when device is removed.
In qeth_remove_device() an interruptible wait operation is used
to wait until a qeth recovery thread is finished. If a user really
interrupts the ungroup operation of a qeth device while a recovery
is running, cio and qeth are out of sync (device already removed
from cio, but kept in qeth). A following module unload of qeth
results in a kernel OOPS here.
Solution:
Do not allow interruption of ungroup operation to guarantee
finishing of a potentially running qeth recovery thread.
Signed-off-by: Ursula Braun <braunu@de.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/s390/net/qeth_main.c | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 57f69434fbf9..ba10d42a1a56 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
@@ -561,7 +561,7 @@ qeth_set_offline(struct ccwgroup_device *cgdev) | |||
561 | } | 561 | } |
562 | 562 | ||
563 | static int | 563 | static int |
564 | qeth_wait_for_threads(struct qeth_card *card, unsigned long threads); | 564 | qeth_threads_running(struct qeth_card *card, unsigned long threads); |
565 | 565 | ||
566 | 566 | ||
567 | static void | 567 | static void |
@@ -576,8 +576,7 @@ qeth_remove_device(struct ccwgroup_device *cgdev) | |||
576 | if (!card) | 576 | if (!card) |
577 | return; | 577 | return; |
578 | 578 | ||
579 | if (qeth_wait_for_threads(card, 0xffffffff)) | 579 | wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0); |
580 | return; | ||
581 | 580 | ||
582 | if (cgdev->state == CCWGROUP_ONLINE){ | 581 | if (cgdev->state == CCWGROUP_ONLINE){ |
583 | card->use_hard_stop = 1; | 582 | card->use_hard_stop = 1; |