Messages in this thread |  | | From | schwidefsky@de ... | Date | Wed, 29 Nov 2000 12:56:44 +0100 | Subject | plug problem in linux-2.4.0-test11 |
| |
Hi, I experienced disk hangs with linux-2.4.0-test11 on S/390 and after some debugging I found the cause. It the new method of unplugging block devices that doesn't go along with the S/390 disk driver:
/* * remove the plug and let it rip.. */ static inline void __generic_unplug_device(request_queue_t *q) { if (!list_empty(&q->queue_head)) { q->plugged = 0; q->request_fn(q); } }
The story goes like this: at start the request queue was empty but the disk driver was still working on an older, already dequeued request. Someone plugged the device (q->plugged = 1 && queue on tq_disk). Then a new request arrived and the unplugging was started. But before __generic_unplug_device was reached the outstanding request finished. The bottom half of the S/390 disk drivers always checks for queued requests after an interrupt, starts the first and dequeues some of the requests on the request queue to put them on its internal queue. You could argue that it shouldn't dequeue request if q->plugged == 1. On the other hand why not, before the disk has nothing to do. Anyway the result was that when the unplug routine was finally reached list_empty was true. In that case q->plugged will not be cleared! The device stays plugged. Forever.
The following implementation works:
/* * remove the plug and let it rip.. */ static inline void __generic_unplug_device(request_queue_t *q) { q->plugged = 0; if (!list_empty(&q->queue_head)) q->request_fn(q); }
blue skies, Martin
Linux/390 Design & Development, IBM Deutschland Entwicklung GmbH Schönaicherstr. 220, D-71032 Böblingen, Telefon: 49 - (0)7031 - 16-2247 E-Mail: schwidefsky@de.ibm.com
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |