Use explicit functions with args instead of work_structs for callbacks.
authorcl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 23 Aug 2005 08:40:50 +0000 (08:40 +0000)
committercl349@firebug.cl.cam.ac.uk <cl349@firebug.cl.cam.ac.uk>
Tue, 23 Aug 2005 08:40:50 +0000 (08:40 +0000)
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
1  2 
linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
linux-2.6-xen-sparse/include/asm-xen/gnttab.h

index 99c68ae11ec94ed47d54df4d7520237bf3b6e228,63deb685f37da369e8a5d18670fddfbe14469657..7a9339d7b8f2307f7e60207917d7fe1ca651dfbf
@@@ -67,16 -65,6 +67,18 @@@ get_free_entry
      return fh;
  }
  
-     struct gnttab_free_callback *callback = gnttab_free_callback_list;
 +static void do_free_callbacks(void)
 +{
-       schedule_work(callback->work);
-       callback = callback->next;
++    struct gnttab_free_callback *callback = gnttab_free_callback_list, *next;
 +    gnttab_free_callback_list = NULL;
 +    while (callback) {
++      next = callback->next;
++      callback->next = NULL;
++      callback->fn(callback->arg);
++      callback = next;
 +    }
 +}
 +
  static inline void
  put_free_entry(
      grant_ref_t ref)
@@@ -264,15 -244,6 +266,18 @@@ gnttab_release_grant_reference( grant_r
      *private_head = release;
  }
  
-                            struct work_struct *work)
 +void
 +gnttab_request_free_callback(struct gnttab_free_callback *callback,
-     callback->work = work;
++                           void (*fn)(void *), void *arg)
 +{
++    if (callback->next)
++      return;
++    callback->fn = fn;
++    callback->arg = arg;
 +    callback->next = gnttab_free_callback_list;
 +    gnttab_free_callback_list = callback;
 +}
 +
  /*
   * ProcFS operations
   */
index 368fb8d1bf1a8efd466bff6c86c33d97de14d7d2,d4e60ace2b963ca7bb6a1e864a743a5283fbd1f2..47576b7d770851dcbeb7464d73fc7dfaadbc8110
@@@ -143,34 -152,30 +143,39 @@@ static inline void flush_requests(struc
  
  module_init(xlblk_init);
  
 -static struct xlbd_disk_info *head_waiting = NULL;
 -static void kick_pending_request_queues(void)
 +static void kick_pending_request_queues(struct blkfront_info *info)
  {
 -    struct xlbd_disk_info *di;
 -    while ( ((di = head_waiting) != NULL) && !RING_FULL(&blk_ring) )
 -    {
 -        head_waiting = di->next_waiting;
 -        di->next_waiting = NULL;
 -        /* Re-enable calldowns. */
 -        blk_start_queue(di->rq);
 -        /* Kick things off immediately. */
 -        do_blkif_request(di->rq);
 -    }
 +      if (!RING_FULL(&info->ring)) {
 +              /* Re-enable calldowns. */
 +              blk_start_queue(info->rq);
 +              /* Kick things off immediately. */
 +              do_blkif_request(info->rq);
 +      }
 +}
 +
 +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;
 -    struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
 +      // struct gendisk *gd = inode->i_bdev->bd_disk;
 +      // struct xlbd_disk_info *di = (struct xlbd_disk_info *)gd->private_data;
  
 -    /* Update of usage count is protected by per-device semaphore. */
 -    di->mi->usage++;
 -    
 -    return 0;
 +      /* Update of usage count is protected by per-device semaphore. */
 +      // di->mi->usage++;
 +
 +      return 0;
  }
  
  
@@@ -232,22 -237,12 +237,20 @@@ static int blkif_queue_request(struct r
      unsigned long id;
      unsigned int fsect, lsect;
      int ref;
 +    grant_ref_t gref_head, gref_terminal;
  
 -    if ( unlikely(blkif_state != BLKIF_STATE_CONNECTED) )
 +    if (unlikely(info->connected != BLKIF_STATE_CONNECTED))
          return 1;
  
-           if (info->callback.work)
-                   return 1;
-           INIT_WORK(&info->work, blkif_restart_queue, (void *)info);
-           gnttab_request_free_callback(&info->callback, &info->work);
 +    if (gnttab_alloc_grant_references(BLKIF_MAX_SEGMENTS_PER_REQUEST,
 +                                    &gref_head, &gref_terminal) < 0) {
++          gnttab_request_free_callback(&info->callback,
++                                       blkif_restart_queue_callback, info);
 +          return 1;
 +    }
 +
      /* Fill out a communications ring structure. */
 -    ring_req = RING_GET_REQUEST(&blk_ring, blk_ring.req_prod_pvt);
 +    ring_req = RING_GET_REQUEST(&info->ring, info->ring.req_prod_pvt);
      id = GET_ID_FROM_FREELIST();
      blk_shadow[id].request = (unsigned long)req;
  
@@@ -1238,10 -1250,9 +1241,11 @@@ static int blkfront_probe(struct xenbus
                xenbus_dev_error(dev, err, "allocating info structure");
                return err;
        }
 -      info->dev = dev;
 +      info->xbdev = dev;
        info->vdevice = vdevice;
 -      info->connected = 0;
 +      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);
index 292652c68125e035d958e9d3343b167e05eb04f3,642a74dbf9b8da6c46010ed4d8788bfdf68e72ea..b5d0de4cc642e2a1f6b67c055beedbf76023ae99
  #define NR_GRANT_FRAMES 4
  #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
  
-     struct work_struct *work;
 +struct work_struct;
 +
 +struct gnttab_free_callback {
 +    struct gnttab_free_callback *next;
++    void (*fn)(void *);
++    void *arg;
 +};
 +
  int
  gnttab_grant_foreign_access(
      domid_t domid, unsigned long frame, int readonly);
@@@ -71,10 -60,6 +72,10 @@@ voi
  gnttab_release_grant_reference(
      grant_ref_t *private_head, grant_ref_t release );
  
-     struct gnttab_free_callback *callback, struct work_struct *work );
 +void
 +gnttab_request_free_callback(
++    struct gnttab_free_callback *callback, void (*fn)(void *), void *arg);
 +
  void
  gnttab_grant_foreign_access_ref(
      grant_ref_t ref, domid_t domid, unsigned long frame, int readonly);