Update scsi host to use ida for host number
PATCH v2 1/1 Update scsi host to use ida for host number
From: Lee Duncan <[email protected]>
Each Scsi_host instance gets a host number starting at 0, but this is implemented with an atomic integer, and rollover doesn't seem to have been considered. Another side-effect of this design is that scsi host numbers used by iscsi are never reused, thereby making rollover more likely. This patch converts Scsi_host instances to use ida to manage their instance numbers.
This also means that host instance numbers will be reused, when available.
Changes from v1:
* Added inline host_put_index() and its use
--- drivers/scsi/hosts.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-)
drivers/scsi/hosts.c +39 -8
@@ -33,7 +33,7 @@#include <linux/transport_class.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> - +#include <linux/idr.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_transport.h>
@@ -42,7 +42,8 @@#include "scsi_logging.h" -static atomic_t scsi_host_next_hn =ATOMIC_INIT (0 );/* host_no for next new host */ +static DEFINE_SPINLOCK (host_index_lock); +static DEFINE_IDA (host_index_ida);static void scsi_host_cls_release (struct device *dev)
@@ -337,6 +338,10 @@ static void scsi_host_dev_release(struct device *dev)kfree (shost->shost_data); +spin_lock (&host_index_lock); +ida_remove (&host_index_ida, shost->host_no); +spin_unlock (&host_index_lock); +if (parent)put_device (parent);kfree (shost);
@@ -353,6 +358,28 @@ static struct device_type scsi_host_type = { .release = scsi_host_dev_release, }; +static int host_get_index (int *index) +{ +int error = -ENOMEM ; + +do { +if (!ida_pre_get (&host_index_ida,GFP_KERNEL )) +break ; +spin_lock (&host_index_lock); + error =ida_get_new (&host_index_ida, index); +spin_unlock (&host_index_lock); + }while (error == -EAGAIN ); + +return error; +} + +static inline void host_put_index (int index) +{ +spin_lock (&host_index_lock); +ida_remove (&host_index_ida, index); +spin_unlock (&host_index_lock); +} +/** * scsi_host_alloc - register a scsi host adapter instance. * @sht: pointer to scsi host template
@@ -370,6 +397,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) {struct Scsi_Host *shost;gfp_t gfp_mask =GFP_KERNEL ; +int index; +int error;if (sht->unchecked_isa_dma && privsize) gfp_mask |= __GFP_DMA;
@@ -388,11 +417,11 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)init_waitqueue_head (&shost->host_wait);mutex_init (&shost->scan_mutex); -/* -* subtract one because we increment first then return, but we need to -* know what the next host number was before increment -*/ - shost->host_no =atomic_inc_return (&scsi_host_next_hn) -1 ; + error =host_get_index (&index); +if (error <0 ) + goto fail_kfree; + shost->host_no = index; + shost->dma_channel =0xff ;/* These three are default values which can be overridden */
@@ -477,7 +506,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)shost_printk (KERN_WARNING , shost,"error handler thread failed to spawn, error = %ld\n" ,PTR_ERR (shost->ehandler)); - goto fail_kfree; + goto fail_free_index; } shost->tmf_work_q = alloc_workqueue("scsi_tmf_%d",
@@ -493,6 +522,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) fail_kthread:kthread_stop (shost->ehandler); + fail_free_index: +host_put_index (index); fail_kfree:kfree (shost);return NULL ;
Signature · 1 line
2.1.4
Quoted 48 lines · On 9/1/2015 8:38 PM, [email protected] wrote:
From: Lee Duncan <[email protected]>
Each
Scsi_hostinstance gets a host number starting at 0, but this is implemented with an atomic integer, and rollover doesn't seem to have been considered. Another side-effect of this design is that scsi host numbers used by iscsi are never reused, thereby making rollover more likely. This patch convertsScsi_hostinstances to use ida to manage their instance numbers.This also means that host instance numbers will be reused, when available.
Changes from v1:
* Added inlinehost_put_index()and its useSigned-off-by Lee Duncan <[email protected]>Reviewed-by Hannes Reinecke <[email protected]>Reviewed-by Johannes Thumshirn <[email protected]>--- drivers/scsi/hosts.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-)drivers/scsi/hosts.c +3
-2@@ -33,7 +33,7 @@#include <linux/transport_class.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> - +#include <linux/idr.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_transport.h> @@ -42,7 +42,8 @@#include "scsi_logging.h" -static atomic_t scsi_host_next_hn =ATOMIC_INIT (0 );/* host_no for next new host */ +static DEFINE_SPINLOCK (host_index_lock); +static DEFINE_IDA (host_index_ida);static void scsi_host_cls_release (struct device *dev)
drivers/scsi/hosts.c static void scsi_host_dev_release(struct device *dev) · line 343
Quoted 6 lines
drivers/scsi/hosts.c +3
-0@@ -337,6 +338,10 @@ static void scsi_host_dev_release(struct device *dev)kfree (shost->shost_data); +spin_lock (&host_index_lock); +ida_remove (&host_index_ida, shost->host_no); +spin_unlock (&host_index_lock);
Why not host_put_index(index)?
Quoted 53 lines · Sagi Grimberg
Quoted 52 lines · On 9/1/2015 8:38 PM, [email protected] wrote:
From: Lee Duncan <[email protected]>
Each
Scsi_hostinstance gets a host number starting at 0, but this is implemented with an atomic integer, and rollover doesn't seem to have been considered. Another side-effect of this design is that scsi host numbers used by iscsi are never reused, thereby making rollover more likely. This patch convertsScsi_hostinstances to use ida to manage their instance numbers.This also means that host instance numbers will be reused, when available.
Changes from v1:
* Added inlinehost_put_index()and its useSigned-off-by Lee Duncan <[email protected]>Reviewed-by Hannes Reinecke <[email protected]>Reviewed-by Johannes Thumshirn <[email protected]>--- drivers/scsi/hosts.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-)drivers/scsi/hosts.c +1
-2@@ -33,7 +33,7 @@#include <linux/transport_class.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> - +#include <linux/idr.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_transport.h> @@ -42,7 +42,8 @@#include "scsi_logging.h" -static atomic_t scsi_host_next_hn =ATOMIC_INIT (0 );/* host_no for next new host */
drivers/scsi/hosts.c +2
-0+static DEFINE_SPINLOCK (host_index_lock); +static DEFINE_IDA (host_index_ida);static void scsi_host_cls_release (struct device *dev)@@ -337,6 +338,10 @@ static void scsi_host_dev_release(struct device *dev)
Quoted 8 lines
drivers/scsi/hosts.c static void scsi_host_dev_release(struct device *dev) · line 343
Quoted 5 lines
drivers/scsi/hosts.c +3
-0kfree (shost->shost_data); +spin_lock (&host_index_lock); +ida_remove (&host_index_ida, shost->host_no); +spin_unlock (&host_index_lock);Why not
host_put_index(index)?
Doh! I'll fix that in both places.
Signature · 1 line
Lee Duncan