aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-06-16 02:22:14 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-21 11:52:42 -0400
commit30c9afa6cc477f6f21f8a0b36f3b81080941a0c9 (patch)
tree863c391cc13e13d005e55096ff3436e973c06453 /drivers
parent111986593561fc4c94a1fba3f3cd84476fb40b22 (diff)
fix race that can give duplicate host number
Just once, two fcoe instances got the same host number from scsi_add_host(). Use atomic_t and atomic_inc_return() to get next host number. Subtract 1, so that scsi_host still starts with 0. [jejb: added comment about unusual subtraction] Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/hosts.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index 89d41a424b33..5fd2da494d08 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -40,7 +40,7 @@
40#include "scsi_logging.h" 40#include "scsi_logging.h"
41 41
42 42
43static int scsi_host_next_hn; /* host_no for next new host */ 43static atomic_t scsi_host_next_hn; /* host_no for next new host */
44 44
45 45
46static void scsi_host_cls_release(struct device *dev) 46static void scsi_host_cls_release(struct device *dev)
@@ -333,7 +333,11 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
333 333
334 mutex_init(&shost->scan_mutex); 334 mutex_init(&shost->scan_mutex);
335 335
336 shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */ 336 /*
337 * subtract one because we increment first then return, but we need to
338 * know what the next host number was before increment
339 */
340 shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
337 shost->dma_channel = 0xff; 341 shost->dma_channel = 0xff;
338 342
339 /* These three are default values which can be overridden */ 343 /* These three are default values which can be overridden */