Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pm8001: add a new spinlock to protect the CCB

Patch adds a new spinlock to protect the ccb management.
It may happen that concurrent threads become the same tag value
from the 'alloc' function', the spinlock prevents this situation.

Signed-off-by: Tomas Henzl <thenzl@redhat.com>
Acked-by: Suresh Thiagarajan <Suresh.Thiagarajan@pmcs.com>
Acked-by: Jack Wang <xjtuwjp@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Tomas Henzl and committed by
Christoph Hellwig
646cdf00 5533abca

+8 -1
+1
drivers/scsi/pm8001/pm8001_init.c
··· 246 246 { 247 247 int i; 248 248 spin_lock_init(&pm8001_ha->lock); 249 + spin_lock_init(&pm8001_ha->bitmap_lock); 249 250 PM8001_INIT_DBG(pm8001_ha, 250 251 pm8001_printk("pm8001_alloc: PHY:%x\n", 251 252 pm8001_ha->chip->n_phy));
+6 -1
drivers/scsi/pm8001/pm8001_sas.c
··· 77 77 { 78 78 unsigned int tag; 79 79 void *bitmap = pm8001_ha->tags; 80 + unsigned long flags; 80 81 82 + spin_lock_irqsave(&pm8001_ha->bitmap_lock, flags); 81 83 tag = find_first_zero_bit(bitmap, pm8001_ha->tags_num); 82 - if (tag >= pm8001_ha->tags_num) 84 + if (tag >= pm8001_ha->tags_num) { 85 + spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags); 83 86 return -SAS_QUEUE_FULL; 87 + } 84 88 set_bit(tag, bitmap); 89 + spin_unlock_irqrestore(&pm8001_ha->bitmap_lock, flags); 85 90 *tag_out = tag; 86 91 return 0; 87 92 }
+1
drivers/scsi/pm8001/pm8001_sas.h
··· 475 475 struct list_head list; 476 476 unsigned long flags; 477 477 spinlock_t lock;/* host-wide lock */ 478 + spinlock_t bitmap_lock; 478 479 struct pci_dev *pdev;/* our device */ 479 480 struct device *dev; 480 481 struct pm8001_hba_memspace io_mem[6];