diff options
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
| -rw-r--r-- | drivers/scsi/scsi_scan.c | 29 | 
1 files changed, 23 insertions, 6 deletions
| diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 9af50e6f94c4..12f54571b83e 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -215,6 +215,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev,  static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,  					   u64 lun, void *hostdata)  { +	unsigned int depth;  	struct scsi_device *sdev;  	int display_failure_msg = 1, ret;  	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -276,8 +277,25 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,  	WARN_ON_ONCE(!blk_get_queue(sdev->request_queue));  	sdev->request_queue->queuedata = sdev; -	scsi_change_queue_depth(sdev, sdev->host->cmd_per_lun ? -					sdev->host->cmd_per_lun : 1); +	depth = sdev->host->cmd_per_lun ?: 1; + +	/* +	 * Use .can_queue as budget map's depth because we have to +	 * support adjusting queue depth from sysfs. Meantime use +	 * default device queue depth to figure out sbitmap shift +	 * since we use this queue depth most of times. +	 */ +	if (sbitmap_init_node(&sdev->budget_map, +				scsi_device_max_queue_depth(sdev), +				sbitmap_calculate_shift(depth), +				GFP_KERNEL, sdev->request_queue->node, +				false, true)) { +		put_device(&starget->dev); +		kfree(sdev); +		goto out; +	} + +	scsi_change_queue_depth(sdev, depth);  	scsi_sysfs_device_initialize(sdev); @@ -979,6 +997,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,  		scsi_attach_vpd(sdev);  	sdev->max_queue_depth = sdev->queue_depth; +	WARN_ON_ONCE(sdev->max_queue_depth > sdev->budget_map.depth);  	sdev->sdev_bflags = *bflags;  	/* @@ -1078,8 +1097,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,  	if (!sdev)  		goto out; -	result = kmalloc(result_len, GFP_KERNEL | -			((shost->unchecked_isa_dma) ? __GFP_DMA : 0)); +	result = kmalloc(result_len, GFP_KERNEL);  	if (!result)  		goto out_free_sdev; @@ -1336,8 +1354,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag  	 */  	length = (511 + 1) * sizeof(struct scsi_lun);  retry: -	lun_data = kmalloc(length, GFP_KERNEL | -			   (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); +	lun_data = kmalloc(length, GFP_KERNEL);  	if (!lun_data) {  		printk(ALLOC_FAILURE_MSG, __func__);  		goto out; | 
