diff options
Diffstat (limited to 'arch/um/drivers/ubd_kern.c')
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index a3061ae39b3b..6cd8988e8fd0 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -106,6 +106,8 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) | |||
106 | 106 | ||
107 | #define DRIVER_NAME "uml-blkdev" | 107 | #define DRIVER_NAME "uml-blkdev" |
108 | 108 | ||
109 | /* Can be taken in interrupt context, and is passed to the block layer to lock | ||
110 | * the request queue. Kernel side code knows that. */ | ||
109 | static DEFINE_SPINLOCK(ubd_io_lock); | 111 | static DEFINE_SPINLOCK(ubd_io_lock); |
110 | 112 | ||
111 | static DEFINE_MUTEX(ubd_lock); | 113 | static DEFINE_MUTEX(ubd_lock); |
@@ -497,6 +499,8 @@ static void __ubd_finish(struct request *req, int error) | |||
497 | end_request(req, 1); | 499 | end_request(req, 1); |
498 | } | 500 | } |
499 | 501 | ||
502 | /* Callable only from interrupt context - otherwise you need to do | ||
503 | * spin_lock_irq()/spin_lock_irqsave() */ | ||
500 | static inline void ubd_finish(struct request *req, int error) | 504 | static inline void ubd_finish(struct request *req, int error) |
501 | { | 505 | { |
502 | spin_lock(&ubd_io_lock); | 506 | spin_lock(&ubd_io_lock); |
@@ -504,7 +508,7 @@ static inline void ubd_finish(struct request *req, int error) | |||
504 | spin_unlock(&ubd_io_lock); | 508 | spin_unlock(&ubd_io_lock); |
505 | } | 509 | } |
506 | 510 | ||
507 | /* Called without ubd_io_lock held */ | 511 | /* Called without ubd_io_lock held, and only in interrupt context. */ |
508 | static void ubd_handler(void) | 512 | static void ubd_handler(void) |
509 | { | 513 | { |
510 | struct io_thread_req req; | 514 | struct io_thread_req req; |
@@ -525,7 +529,9 @@ static void ubd_handler(void) | |||
525 | 529 | ||
526 | ubd_finish(rq, req.error); | 530 | ubd_finish(rq, req.error); |
527 | reactivate_fd(thread_fd, UBD_IRQ); | 531 | reactivate_fd(thread_fd, UBD_IRQ); |
532 | spin_lock(&ubd_io_lock); | ||
528 | do_ubd_request(ubd_queue); | 533 | do_ubd_request(ubd_queue); |
534 | spin_unlock(&ubd_io_lock); | ||
529 | } | 535 | } |
530 | 536 | ||
531 | static irqreturn_t ubd_intr(int irq, void *dev) | 537 | static irqreturn_t ubd_intr(int irq, void *dev) |