From: Matthew Wilcox Date: Fri, 15 Feb 2019 13:06:23 +0000 (-0500) Subject: visorhba: Convert to XArray X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=db2a53356357cd94bcd435e83ddfee82d3121bb8;p=users%2Fwilly%2Fxarray.git visorhba: Convert to XArray Signed-off-by: Matthew Wilcox --- diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c index dd979ee4dcf1..ec689c47e21b 100644 --- a/drivers/staging/unisys/visorhba/visorhba_main.c +++ b/drivers/staging/unisys/visorhba/visorhba_main.c @@ -6,10 +6,10 @@ #include #include -#include #include #include #include +#include #include #include #include @@ -86,7 +86,7 @@ struct visorhba_devdata { * allows us to pass int handles back-and-forth between us and * iovm, instead of raw pointers */ - struct idr idr; + struct xarray handles; struct dentry *debugfs_dir; struct dentry *debugfs_info; @@ -219,71 +219,55 @@ static struct uiscmdrsp *get_scsipending_cmdrsp(struct visorhba_devdata *ddata, return NULL; } -/* - * simple_idr_get - Associate a provided pointer with an int value - * 1 <= value <= INT_MAX, and return this int value; - * the pointer value can be obtained later by passing - * this int value to idr_find() - * @idrtable: The data object maintaining the pointer<-->int mappings - * @p: The pointer value to be remembered - * @lock: A spinlock used when exclusive access to idrtable is needed - * - * Return: The id number mapped to pointer 'p', 0 on failure - */ -static unsigned int simple_idr_get(struct idr *idrtable, void *p, - spinlock_t *lock) -{ - int id; - unsigned long flags; - - idr_preload(GFP_KERNEL); - spin_lock_irqsave(lock, flags); - id = idr_alloc(idrtable, p, 1, INT_MAX, GFP_NOWAIT); - spin_unlock_irqrestore(lock, flags); - idr_preload_end(); - /* failure */ - if (id < 0) - return 0; - /* idr_alloc() guarantees > 0 */ - return (unsigned int)(id); -} - /* * setup_scsitaskmgmt_handles - Stash the necessary handles so that the * completion processing logic for a taskmgmt * cmd will be able to find who to wake up * and where to stash the result - * @idrtable: The data object maintaining the pointer<-->int mappings - * @lock: A spinlock used when exclusive access to idrtable is needed + * @devdata: Pointer to devdata * @cmdrsp: Response from the IOVM * @event: The event handle to associate with an id * @result: The location to place the result of the event handle into */ -static void setup_scsitaskmgmt_handles(struct idr *idrtable, spinlock_t *lock, +static void setup_scsitaskmgmt_handles(struct visorhba_devdata *devdata, struct uiscmdrsp *cmdrsp, wait_queue_head_t *event, int *result) { + int ret, handle; + /* specify the event that has to be triggered when this */ /* cmd is complete */ - cmdrsp->scsitaskmgmt.notify_handle = - simple_idr_get(idrtable, event, lock); - cmdrsp->scsitaskmgmt.notifyresult_handle = - simple_idr_get(idrtable, result, lock); + ret = xa_alloc_irq(&devdata->handles, &handle, event, + xa_limit_31b, GFP_KERNEL); + if (ret) + cmdrsp->scsitaskmgmt.notify_handle = 0; + else + cmdrsp->scsitaskmgmt.notify_handle = handle; + + ret = xa_alloc_irq(&devdata->handles, &handle, result, + xa_limit_31b, GFP_KERNEL); + if (ret) + cmdrsp->scsitaskmgmt.notifyresult_handle = 0; + else + cmdrsp->scsitaskmgmt.notifyresult_handle = handle; + } /* * cleanup_scsitaskmgmt_handles - Forget handles created by * setup_scsitaskmgmt_handles() - * @idrtable: The data object maintaining the pointer<-->int mappings + * @devdata: Pointer to devdata * @cmdrsp: Response from the IOVM */ -static void cleanup_scsitaskmgmt_handles(struct idr *idrtable, +static void cleanup_scsitaskmgmt_handles(struct visorhba_devdata *devdata, struct uiscmdrsp *cmdrsp) { if (cmdrsp->scsitaskmgmt.notify_handle) - idr_remove(idrtable, cmdrsp->scsitaskmgmt.notify_handle); + xa_erase_irq(&devdata->handles, + cmdrsp->scsitaskmgmt.notify_handle); if (cmdrsp->scsitaskmgmt.notifyresult_handle) - idr_remove(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle); + xa_erase_irq(&devdata->handles, + cmdrsp->scsitaskmgmt.notifyresult_handle); } /* @@ -321,8 +305,8 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, /* issue TASK_MGMT_ABORT_TASK */ cmdrsp->cmdtype = CMD_SCSITASKMGMT_TYPE; - setup_scsitaskmgmt_handles(&devdata->idr, &devdata->privlock, cmdrsp, - ¬ifyevent, ¬ifyresult); + setup_scsitaskmgmt_handles(devdata, cmdrsp, ¬ifyevent, + ¬ifyresult); /* save destination */ cmdrsp->scsitaskmgmt.tasktype = tasktype; @@ -348,14 +332,14 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype, dev_dbg(&scsidev->sdev_gendev, "visorhba: taskmgmt type=%d success; result=0x%x\n", tasktype, notifyresult); - cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp); + cleanup_scsitaskmgmt_handles(devdata, cmdrsp); return SUCCESS; err_del_scsipending_ent: dev_dbg(&scsidev->sdev_gendev, "visorhba: taskmgmt type=%d not executed\n", tasktype); del_scsipending_ent(devdata, scsicmd_id); - cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp); + cleanup_scsitaskmgmt_handles(devdata, cmdrsp); return FAILED; } @@ -684,20 +668,21 @@ DEFINE_SHOW_ATTRIBUTE(info_debugfs); /* * complete_taskmgmt_command - Complete task management - * @idrtable: The data object maintaining the pointer<-->int mappings + * @devdata: Pointer to devdata * @cmdrsp: Response from the IOVM * @result: The result of the task management command * * Service Partition returned the result of the task management * command. Wake up anyone waiting for it. */ -static void complete_taskmgmt_command(struct idr *idrtable, +static void complete_taskmgmt_command(struct visorhba_devdata *devdata, struct uiscmdrsp *cmdrsp, int result) { - wait_queue_head_t *wq = - idr_find(idrtable, cmdrsp->scsitaskmgmt.notify_handle); - int *scsi_result_ptr = - idr_find(idrtable, cmdrsp->scsitaskmgmt.notifyresult_handle); + wait_queue_head_t *wq = xa_load(&devdata->handles, + cmdrsp->scsitaskmgmt.notify_handle); + int *scsi_result_ptr = xa_load(&devdata->handles, + cmdrsp->scsitaskmgmt.notifyresult_handle); + if (unlikely(!(wq && scsi_result_ptr))) { pr_err("visorhba: no completion context; cmd will time out\n"); return; @@ -745,7 +730,7 @@ static void visorhba_serverdown_complete(struct visorhba_devdata *devdata) break; case CMD_SCSITASKMGMT_TYPE: cmdrsp = pendingdel->sent; - complete_taskmgmt_command(&devdata->idr, cmdrsp, + complete_taskmgmt_command(devdata, cmdrsp, TASK_MGMT_FAILED); break; default: @@ -942,7 +927,7 @@ static void drain_queue(struct uiscmdrsp *cmdrsp, if (!del_scsipending_ent(devdata, cmdrsp->scsitaskmgmt.handle)) break; - complete_taskmgmt_command(&devdata->idr, cmdrsp, + complete_taskmgmt_command(devdata, cmdrsp, cmdrsp->scsitaskmgmt.result); } else if (cmdrsp->cmdtype == CMD_NOTIFYGUEST_TYPE) dev_err_once(&devdata->dev->device, @@ -1111,7 +1096,7 @@ static int visorhba_probe(struct visor_device *dev) if (err) goto err_debugfs_info; - idr_init(&devdata->idr); + xa_init_flags(&devdata->handles, XA_FLAGS_ALLOC1); devdata->thread_wait_ms = 2; devdata->thread = visor_thread_start(process_incoming_rsps, devdata, @@ -1154,8 +1139,6 @@ static void visorhba_remove(struct visor_device *dev) scsi_remove_host(scsihost); scsi_host_put(scsihost); - idr_destroy(&devdata->idr); - dev_set_drvdata(&dev->device, NULL); debugfs_remove(devdata->debugfs_info); debugfs_remove_recursive(devdata->debugfs_dir);