Update scsi host to use ida for host number
PATCH 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.
--- drivers/scsi/hosts.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-)
drivers/scsi/hosts.c +35 -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,22 @@ 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; +} + +/** * scsi_host_alloc - register a scsi host adapter instance. * @sht: pointer to scsi host template
@@ -370,6 +391,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 +411,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 +500,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 +516,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) fail_kthread:kthread_stop (shost->ehandler); + fail_free_index: +spin_lock (&host_index_lock); +ida_remove (&host_index_ida, index); +spin_unlock (&host_index_lock); fail_kfree:kfree (shost);return NULL ;
Signature · 1 line
2.1.4
Quoted 113 lines · On 08/31/2015 10:28 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.
Signed-off-by Lee Duncan <[email protected]>--- drivers/scsi/hosts.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-)drivers/scsi/hosts.c +31
-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,22 @@ 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; +} + +/** * scsi_host_alloc - register a scsi host adapter instance. * @sht: pointer to scsi host template @@ -370,6 +391,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 +411,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 +500,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",
drivers/scsi/hosts.c struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) · line 525
Quoted 10 lines
drivers/scsi/hosts.c +4
-0@@ -493,6 +516,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) fail_kthread:kthread_stop (shost->ehandler); + fail_free_index: +spin_lock (&host_index_lock); +ida_remove (&host_index_ida, index); +spin_unlock (&host_index_lock); fail_kfree:kfree (shost);return NULL ;
Cheers,
Hannes
Quoted 112 lines · [email protected] writes:
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.
Signed-off-by Lee Duncan <[email protected]>--- drivers/scsi/hosts.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-)drivers/scsi/hosts.c +31
-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,22 @@ 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; +} + +/** * scsi_host_alloc - register a scsi host adapter instance. * @sht: pointer to scsi host template @@ -370,6 +391,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 +411,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 +500,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",
drivers/scsi/hosts.c struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) · line 525
Quoted 10 lines
drivers/scsi/hosts.c +4
-0@@ -493,6 +516,10 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) fail_kthread:kthread_stop (shost->ehandler); + fail_free_index: +spin_lock (&host_index_lock); +ida_remove (&host_index_ida, index); +spin_unlock (&host_index_lock); fail_kfree:kfree (shost);return NULL ;
Signature · 10 lines
Johannes Thumshirn Storage [email protected] +49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Quoted 43 lines · On 8/31/2015 11:28 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.
Signed-off-by Lee Duncan <[email protected]>--- drivers/scsi/hosts.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 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 get it in a symmetrical host_put_index()
Quoted 47 lines · Sagi Grimberg
Quoted 46 lines · On 8/31/2015 11:28 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.
Signed-off-by Lee Duncan <[email protected]>--- drivers/scsi/hosts.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 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 7 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 get it in a symmetrical
host_put_index()
Seems like a reasonable suggestion. Since it's only 3 statements, I'll make it an inline.
I will resubmit the patch, adding the two reviewed-by lines from Hannes and Johannes, since the code will essentially be the same.
Signature · 2 lines
Lee Duncan SUSE Labs