diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c index 99c68ae11e..7a9339d7b8 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c @@ -69,11 +69,13 @@ get_free_entry( static void do_free_callbacks(void) { - struct gnttab_free_callback *callback = gnttab_free_callback_list; + struct gnttab_free_callback *callback = gnttab_free_callback_list, *next; gnttab_free_callback_list = NULL; while (callback) { - schedule_work(callback->work); - callback = callback->next; + next = callback->next; + callback->next = NULL; + callback->fn(callback->arg); + callback = next; } } @@ -266,9 +268,12 @@ gnttab_release_grant_reference( grant_ref_t *private_head, void gnttab_request_free_callback(struct gnttab_free_callback *callback, - struct work_struct *work) + void (*fn)(void *), void *arg) { - callback->work = work; + if (callback->next) + return; + callback->fn = fn; + callback->arg = arg; callback->next = gnttab_free_callback_list; gnttab_free_callback_list = callback; } diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index 368fb8d1bf..47576b7d77 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -157,11 +157,16 @@ static void blkif_restart_queue(void *arg) { struct blkfront_info *info = (struct blkfront_info *)arg; spin_lock_irq(&blkif_io_lock); - info->callback.work = NULL; kick_pending_request_queues(info); spin_unlock_irq(&blkif_io_lock); } +static void blkif_restart_queue_callback(void *arg) +{ + struct blkfront_info *info = (struct blkfront_info *)arg; + schedule_work(&info->work); +} + int blkif_open(struct inode *inode, struct file *filep) { // struct gendisk *gd = inode->i_bdev->bd_disk; @@ -239,10 +244,8 @@ static int blkif_queue_request(struct request *req) if (gnttab_alloc_grant_references(BLKIF_MAX_SEGMENTS_PER_REQUEST, &gref_head, &gref_terminal) < 0) { - if (info->callback.work) - return 1; - INIT_WORK(&info->work, blkif_restart_queue, (void *)info); - gnttab_request_free_callback(&info->callback, &info->work); + gnttab_request_free_callback(&info->callback, + blkif_restart_queue_callback, info); return 1; } @@ -1242,6 +1245,7 @@ static int blkfront_probe(struct xenbus_device *dev, info->vdevice = vdevice; info->connected = BLKIF_STATE_DISCONNECTED; info->mi = NULL; + INIT_WORK(&info->work, blkif_restart_queue, (void *)info); /* Front end dir is a number, which is used as the id. */ info->handle = simple_strtoul(strrchr(dev->nodename,'/')+1, NULL, 0); diff --git a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h index 292652c681..b5d0de4cc6 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/gnttab.h +++ b/linux-2.6-xen-sparse/include/asm-xen/gnttab.h @@ -25,7 +25,8 @@ struct work_struct; struct gnttab_free_callback { struct gnttab_free_callback *next; - struct work_struct *work; + void (*fn)(void *); + void *arg; }; int @@ -73,7 +74,7 @@ gnttab_release_grant_reference( void gnttab_request_free_callback( - struct gnttab_free_callback *callback, struct work_struct *work ); + struct gnttab_free_callback *callback, void (*fn)(void *), void *arg); void gnttab_grant_foreign_access_ref(