scsi: visorhba: sanitze private device data allocation

There's no need to keep the private data for a device in a separate
list; better to store it in ->hostdata and do away with the additional
list.

Signed-off-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: David Kershner <david.kershner@unisys.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Hannes Reinecke 2017-08-25 13:57:20 +02:00 коммит произвёл Martin K. Petersen
Родитель 6d415342ad
Коммит 7bc4e528d9
1 изменённых файлов: 53 добавлений и 70 удалений

Просмотреть файл

@ -47,8 +47,8 @@ MODULE_DEVICE_TABLE(visorbus, visorhba_channel_types);
MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR); MODULE_ALIAS("visorbus:" VISOR_VHBA_CHANNEL_UUID_STR);
struct visordisk_info { struct visordisk_info {
struct scsi_device *sdev;
u32 valid; u32 valid;
u32 channel, id, lun; /* Disk Path */
atomic_t ios_threshold; atomic_t ios_threshold;
atomic_t error_count; atomic_t error_count;
struct visordisk_info *next; struct visordisk_info *next;
@ -101,12 +101,6 @@ struct visorhba_devices_open {
struct visorhba_devdata *devdata; struct visorhba_devdata *devdata;
}; };
#define for_each_vdisk_match(iter, list, match) \
for (iter = &list->head; iter->next; iter = iter->next) \
if ((iter->channel == match->channel) && \
(iter->id == match->id) && \
(iter->lun == match->lun))
/* /*
* visor_thread_start - starts a thread for the device * visor_thread_start - starts a thread for the device
* @threadfn: Function the thread starts * @threadfn: Function the thread starts
@ -296,10 +290,9 @@ static void cleanup_scsitaskmgmt_handles(struct idr *idrtable,
* Returns whether the command was queued successfully or not. * Returns whether the command was queued successfully or not.
*/ */
static int forward_taskmgmt_command(enum task_mgmt_types tasktype, static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
struct scsi_cmnd *scsicmd) struct scsi_device *scsidev)
{ {
struct uiscmdrsp *cmdrsp; struct uiscmdrsp *cmdrsp;
struct scsi_device *scsidev = scsicmd->device;
struct visorhba_devdata *devdata = struct visorhba_devdata *devdata =
(struct visorhba_devdata *)scsidev->host->hostdata; (struct visorhba_devdata *)scsidev->host->hostdata;
int notifyresult = 0xffff; int notifyresult = 0xffff;
@ -347,12 +340,6 @@ static int forward_taskmgmt_command(enum task_mgmt_types tasktype,
dev_dbg(&scsidev->sdev_gendev, dev_dbg(&scsidev->sdev_gendev,
"visorhba: taskmgmt type=%d success; result=0x%x\n", "visorhba: taskmgmt type=%d success; result=0x%x\n",
tasktype, notifyresult); tasktype, notifyresult);
if (tasktype == TASK_MGMT_ABORT_TASK)
scsicmd->result = DID_ABORT << 16;
else
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp); cleanup_scsitaskmgmt_handles(&devdata->idr, cmdrsp);
return SUCCESS; return SUCCESS;
@ -376,17 +363,20 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
/* issue TASK_MGMT_ABORT_TASK */ /* issue TASK_MGMT_ABORT_TASK */
struct scsi_device *scsidev; struct scsi_device *scsidev;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata; int rtn;
scsidev = scsicmd->device; scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count); atomic_inc(&vdisk->error_count);
else else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
rtn = forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_ABORT << 16;
scsicmd->scsi_done(scsicmd);
} }
return forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsicmd); return rtn;
} }
/* /*
@ -400,17 +390,20 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
/* issue TASK_MGMT_LUN_RESET */ /* issue TASK_MGMT_LUN_RESET */
struct scsi_device *scsidev; struct scsi_device *scsidev;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata; int rtn;
scsidev = scsicmd->device; scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count); atomic_inc(&vdisk->error_count);
else else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
} }
return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsicmd); return rtn;
} }
/* /*
@ -424,17 +417,22 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
{ {
struct scsi_device *scsidev; struct scsi_device *scsidev;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata; int rtn;
scsidev = scsicmd->device; scsidev = scsicmd->device;
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; shost_for_each_device(scsidev, scsidev->host) {
for_each_vdisk_match(vdisk, devdata, scsidev) { vdisk = scsidev->hostdata;
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
atomic_inc(&vdisk->error_count); atomic_inc(&vdisk->error_count);
else else
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
} }
return forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsicmd); rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev);
if (rtn == SUCCESS) {
scsicmd->result = DID_RESET << 16;
scsicmd->scsi_done(scsicmd);
}
return rtn;
} }
/* /*
@ -569,25 +567,22 @@ static int visorhba_slave_alloc(struct scsi_device *scsidev)
* LLD can alloc any struct & do init if needed. * LLD can alloc any struct & do init if needed.
*/ */
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visordisk_info *tmpvdisk;
struct visorhba_devdata *devdata; struct visorhba_devdata *devdata;
struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host; struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
if (scsidev->hostdata)
return 0; /* already allocated return success */
devdata = (struct visorhba_devdata *)scsihost->hostdata; devdata = (struct visorhba_devdata *)scsihost->hostdata;
if (!devdata) if (!devdata)
return 0; /* even though we errored, treat as success */ return 0; /* even though we errored, treat as success */
for_each_vdisk_match(vdisk, devdata, scsidev) vdisk = kzalloc(sizeof(*vdisk), GFP_ATOMIC);
return 0; /* already allocated return success */ if (!vdisk)
tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
if (!tmpvdisk)
return -ENOMEM; return -ENOMEM;
tmpvdisk->channel = scsidev->channel; vdisk->sdev = scsidev;
tmpvdisk->id = scsidev->id; scsidev->hostdata = vdisk;
tmpvdisk->lun = scsidev->lun;
vdisk->next = tmpvdisk;
return 0; return 0;
} }
@ -603,17 +598,11 @@ static void visorhba_slave_destroy(struct scsi_device *scsidev)
/* midlevel calls this after device has been quiesced and /* midlevel calls this after device has been quiesced and
* before it is to be deleted. * before it is to be deleted.
*/ */
struct visordisk_info *vdisk, *delvdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
devdata = (struct visorhba_devdata *)scsihost->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) { scsidev->hostdata = NULL;
delvdisk = vdisk->next; kfree(vdisk);
vdisk->next = delvdisk->next;
kfree(delvdisk);
return;
}
} }
static struct scsi_host_template visorhba_driver_template = { static struct scsi_host_template visorhba_driver_template = {
@ -787,7 +776,6 @@ static int visorhba_serverdown(struct visorhba_devdata *devdata)
static void static void
do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd) do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
{ {
struct visorhba_devdata *devdata;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct scsi_device *scsidev; struct scsi_device *scsidev;
@ -800,14 +788,12 @@ do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
(cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT)) (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT))
return; return;
/* Okay see what our error_count is here.... */ /* Okay see what our error_count is here.... */
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) { if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT) {
atomic_inc(&vdisk->error_count); atomic_inc(&vdisk->error_count);
atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD); atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
} }
} }
}
static int set_no_disk_inquiry_result(unsigned char *buf, static int set_no_disk_inquiry_result(unsigned char *buf,
size_t len, bool is_lun0) size_t len, bool is_lun0)
@ -846,7 +832,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
char *this_page_orig; char *this_page_orig;
int bufind = 0; int bufind = 0;
struct visordisk_info *vdisk; struct visordisk_info *vdisk;
struct visorhba_devdata *devdata;
scsidev = scsicmd->device; scsidev = scsicmd->device;
if ((cmdrsp->scsi.cmnd[0] == INQUIRY) && if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
@ -883,8 +868,7 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
} }
kfree(buf); kfree(buf);
} else { } else {
devdata = (struct visorhba_devdata *)scsidev->host->hostdata; vdisk = scsidev->hostdata;
for_each_vdisk_match(vdisk, devdata, scsidev) {
if (atomic_read(&vdisk->ios_threshold) > 0) { if (atomic_read(&vdisk->ios_threshold) > 0) {
atomic_dec(&vdisk->ios_threshold); atomic_dec(&vdisk->ios_threshold);
if (atomic_read(&vdisk->ios_threshold) == 0) if (atomic_read(&vdisk->ios_threshold) == 0)
@ -892,7 +876,6 @@ do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
} }
} }
} }
}
/* /*
* complete_scsi_command - complete a scsi command * complete_scsi_command - complete a scsi command