aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-03-29 04:20:27 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-29 11:22:24 -0400
commit2a9529a0c890007ade5425b75272c3def283f8b1 (patch)
tree964576fad2872f41e798e109979daad4002007af /arch/um/drivers
parentcb3fecc2f29056e89658e7eb371e7f9be66cda6d (diff)
[PATCH] uml: fix I/O hang when multiple devices are in use
Commit 62f96cb01e8de7a5daee472e540f726db2801499 introduced per-devices queues and locks, which was fine as far as it went, but left in place a global which controlled access to submitting requests to the host. This should have been made per-device as well, since it causes I/O hangs when multiple block devices are in use. This patch fixes that by replacing the global with an activity flag in the device structure in order to tell whether the queue is currently being run. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/drivers')
-rw-r--r--arch/um/drivers/ubd_kern.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index f98d26e51381..8bd9204ac1ab 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -109,10 +109,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
109 109
110static DEFINE_MUTEX(ubd_lock); 110static DEFINE_MUTEX(ubd_lock);
111 111
112/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and
113 * probably it doesn't make sense even for that. */
114static int do_ubd;
115
116static int ubd_open(struct inode * inode, struct file * filp); 112static int ubd_open(struct inode * inode, struct file * filp);
117static int ubd_release(struct inode * inode, struct file * file); 113static int ubd_release(struct inode * inode, struct file * file);
118static int ubd_ioctl(struct inode * inode, struct file * file, 114static int ubd_ioctl(struct inode * inode, struct file * file,
@@ -169,6 +165,7 @@ struct ubd {
169 struct platform_device pdev; 165 struct platform_device pdev;
170 struct request_queue *queue; 166 struct request_queue *queue;
171 spinlock_t lock; 167 spinlock_t lock;
168 int active;
172}; 169};
173 170
174#define DEFAULT_COW { \ 171#define DEFAULT_COW { \
@@ -190,6 +187,7 @@ struct ubd {
190 .shared = 0, \ 187 .shared = 0, \
191 .cow = DEFAULT_COW, \ 188 .cow = DEFAULT_COW, \
192 .lock = SPIN_LOCK_UNLOCKED, \ 189 .lock = SPIN_LOCK_UNLOCKED, \
190 .active = 0, \
193} 191}
194 192
195/* Protected by ubd_lock */ 193/* Protected by ubd_lock */
@@ -507,7 +505,6 @@ static void ubd_handler(void)
507 struct ubd *dev; 505 struct ubd *dev;
508 int n; 506 int n;
509 507
510 do_ubd = 0;
511 n = os_read_file(thread_fd, &req, sizeof(req)); 508 n = os_read_file(thread_fd, &req, sizeof(req));
512 if(n != sizeof(req)){ 509 if(n != sizeof(req)){
513 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " 510 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
@@ -517,6 +514,7 @@ static void ubd_handler(void)
517 514
518 rq = req.req; 515 rq = req.req;
519 dev = rq->rq_disk->private_data; 516 dev = rq->rq_disk->private_data;
517 dev->active = 0;
520 518
521 ubd_finish(rq, req.error); 519 ubd_finish(rq, req.error);
522 reactivate_fd(thread_fd, UBD_IRQ); 520 reactivate_fd(thread_fd, UBD_IRQ);
@@ -1081,11 +1079,12 @@ static void do_ubd_request(request_queue_t *q)
1081 } 1079 }
1082 } 1080 }
1083 else { 1081 else {
1084 if(do_ubd || (req = elv_next_request(q)) == NULL) 1082 struct ubd *dev = q->queuedata;
1083 if(dev->active || (req = elv_next_request(q)) == NULL)
1085 return; 1084 return;
1086 err = prepare_request(req, &io_req); 1085 err = prepare_request(req, &io_req);
1087 if(!err){ 1086 if(!err){
1088 do_ubd = 1; 1087 dev->active = 1;
1089 n = os_write_file(thread_fd, (char *) &io_req, 1088 n = os_write_file(thread_fd, (char *) &io_req,
1090 sizeof(io_req)); 1089 sizeof(io_req));
1091 if(n != sizeof(io_req)) 1090 if(n != sizeof(io_req))