scsi: fix the {host,target,device}_blocked counter mess
Seems like these counters are missing any sort of synchronization for updates, as a over 10 year old comment from me noted. Fix this by using atomic counters, and while we're at it also make sure they are in the same cacheline as the _busy counters and not needlessly stored to in every I/O completion. With the new model the _busy counters can temporarily go negative, so all the readers are updated to check for > 0 values. Longer term every successful I/O completion will reset the counters to zero, so the temporarily negative values will not cause any harm. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Webb Scales <webbnh@hp.com> Acked-by: Jens Axboe <axboe@kernel.dk> Tested-by: Bart Van Assche <bvanassche@acm.org> Tested-by: Robert Elliott <elliott@hp.com>
This commit is contained in:
@@ -584,7 +584,6 @@ static int scsi_sdev_check_buf_bit(const char *buf)
|
||||
/*
|
||||
* Create the actual show/store functions and data structures.
|
||||
*/
|
||||
sdev_rd_attr (device_blocked, "%d\n");
|
||||
sdev_rd_attr (type, "%d\n");
|
||||
sdev_rd_attr (scsi_level, "%d\n");
|
||||
sdev_rd_attr (vendor, "%.8s\n");
|
||||
@@ -600,6 +599,15 @@ sdev_show_device_busy(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
static DEVICE_ATTR(device_busy, S_IRUGO, sdev_show_device_busy, NULL);
|
||||
|
||||
static ssize_t
|
||||
sdev_show_device_blocked(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
return snprintf(buf, 20, "%d\n", atomic_read(&sdev->device_blocked));
|
||||
}
|
||||
static DEVICE_ATTR(device_blocked, S_IRUGO, sdev_show_device_blocked, NULL);
|
||||
|
||||
/*
|
||||
* TODO: can we make these symlinks to the block layer ones?
|
||||
*/
|
||||
|
Reference in New Issue
Block a user