Skip to content

Commit 78ca558

Browse files
committed
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI fixes from James Bottomley: "Eight fixes, all in drivers (ufs, scsi_debug, storvsc, iscsi, ibmvfc). Apart from the ufs command clearing updates, these are mostly minor and obvious fixes" * tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: scsi: ibmvfc: Store vhost pointer during subcrq allocation scsi: ibmvfc: Allocate/free queue resource only during probe/remove scsi: storvsc: Correct reporting of Hyper-V I/O size limits scsi: ufs: Fix a race between the interrupt handler and the reset handler scsi: ufs: Support clearing multiple commands at once scsi: ufs: Simplify ufshcd_clear_cmd() scsi: iscsi: Exclude zero from the endpoint ID range scsi: scsi_debug: Fix zone transition to full condition
2 parents c5b3a09 + aeaadcd commit 78ca558

File tree

6 files changed

+161
-55
lines changed

6 files changed

+161
-55
lines changed

drivers/scsi/ibmvscsi/ibmvfc.c

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ static void ibmvfc_npiv_logout(struct ibmvfc_host *);
160160
static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *);
161161
static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
162162

163-
static void ibmvfc_release_sub_crqs(struct ibmvfc_host *);
164-
static void ibmvfc_init_sub_crqs(struct ibmvfc_host *);
163+
static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *);
164+
static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *);
165165

166166
static const char *unknown_error = "unknown error";
167167

@@ -917,7 +917,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
917917
struct vio_dev *vdev = to_vio_dev(vhost->dev);
918918
unsigned long flags;
919919

920-
ibmvfc_release_sub_crqs(vhost);
920+
ibmvfc_dereg_sub_crqs(vhost);
921921

922922
/* Re-enable the CRQ */
923923
do {
@@ -936,7 +936,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost)
936936
spin_unlock(vhost->crq.q_lock);
937937
spin_unlock_irqrestore(vhost->host->host_lock, flags);
938938

939-
ibmvfc_init_sub_crqs(vhost);
939+
ibmvfc_reg_sub_crqs(vhost);
940940

941941
return rc;
942942
}
@@ -955,7 +955,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
955955
struct vio_dev *vdev = to_vio_dev(vhost->dev);
956956
struct ibmvfc_queue *crq = &vhost->crq;
957957

958-
ibmvfc_release_sub_crqs(vhost);
958+
ibmvfc_dereg_sub_crqs(vhost);
959959

960960
/* Close the CRQ */
961961
do {
@@ -988,7 +988,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
988988
spin_unlock(vhost->crq.q_lock);
989989
spin_unlock_irqrestore(vhost->host->host_lock, flags);
990990

991-
ibmvfc_init_sub_crqs(vhost);
991+
ibmvfc_reg_sub_crqs(vhost);
992992

993993
return rc;
994994
}
@@ -5682,6 +5682,8 @@ static int ibmvfc_alloc_queue(struct ibmvfc_host *vhost,
56825682
queue->cur = 0;
56835683
queue->fmt = fmt;
56845684
queue->size = PAGE_SIZE / fmt_size;
5685+
5686+
queue->vhost = vhost;
56855687
return 0;
56865688
}
56875689

@@ -5757,9 +5759,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
57575759

57585760
ENTER;
57595761

5760-
if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT))
5761-
return -ENOMEM;
5762-
57635762
rc = h_reg_sub_crq(vdev->unit_address, scrq->msg_token, PAGE_SIZE,
57645763
&scrq->cookie, &scrq->hw_irq);
57655764

@@ -5790,7 +5789,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
57905789
}
57915790

57925791
scrq->hwq_id = index;
5793-
scrq->vhost = vhost;
57945792

57955793
LEAVE;
57965794
return 0;
@@ -5800,7 +5798,6 @@ static int ibmvfc_register_scsi_channel(struct ibmvfc_host *vhost,
58005798
rc = plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cookie);
58015799
} while (rtas_busy_delay(rc));
58025800
reg_failed:
5803-
ibmvfc_free_queue(vhost, scrq);
58045801
LEAVE;
58055802
return rc;
58065803
}
@@ -5826,12 +5823,50 @@ static void ibmvfc_deregister_scsi_channel(struct ibmvfc_host *vhost, int index)
58265823
if (rc)
58275824
dev_err(dev, "Failed to free sub-crq[%d]: rc=%ld\n", index, rc);
58285825

5829-
ibmvfc_free_queue(vhost, scrq);
5826+
/* Clean out the queue */
5827+
memset(scrq->msgs.crq, 0, PAGE_SIZE);
5828+
scrq->cur = 0;
5829+
5830+
LEAVE;
5831+
}
5832+
5833+
static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *vhost)
5834+
{
5835+
int i, j;
5836+
5837+
ENTER;
5838+
if (!vhost->mq_enabled || !vhost->scsi_scrqs.scrqs)
5839+
return;
5840+
5841+
for (i = 0; i < nr_scsi_hw_queues; i++) {
5842+
if (ibmvfc_register_scsi_channel(vhost, i)) {
5843+
for (j = i; j > 0; j--)
5844+
ibmvfc_deregister_scsi_channel(vhost, j - 1);
5845+
vhost->do_enquiry = 0;
5846+
return;
5847+
}
5848+
}
5849+
5850+
LEAVE;
5851+
}
5852+
5853+
static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *vhost)
5854+
{
5855+
int i;
5856+
5857+
ENTER;
5858+
if (!vhost->mq_enabled || !vhost->scsi_scrqs.scrqs)
5859+
return;
5860+
5861+
for (i = 0; i < nr_scsi_hw_queues; i++)
5862+
ibmvfc_deregister_scsi_channel(vhost, i);
5863+
58305864
LEAVE;
58315865
}
58325866

58335867
static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
58345868
{
5869+
struct ibmvfc_queue *scrq;
58355870
int i, j;
58365871

58375872
ENTER;
@@ -5847,30 +5882,41 @@ static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost)
58475882
}
58485883

58495884
for (i = 0; i < nr_scsi_hw_queues; i++) {
5850-
if (ibmvfc_register_scsi_channel(vhost, i)) {
5851-
for (j = i; j > 0; j--)
5852-
ibmvfc_deregister_scsi_channel(vhost, j - 1);
5885+
scrq = &vhost->scsi_scrqs.scrqs[i];
5886+
if (ibmvfc_alloc_queue(vhost, scrq, IBMVFC_SUB_CRQ_FMT)) {
5887+
for (j = i; j > 0; j--) {
5888+
scrq = &vhost->scsi_scrqs.scrqs[j - 1];
5889+
ibmvfc_free_queue(vhost, scrq);
5890+
}
58535891
kfree(vhost->scsi_scrqs.scrqs);
58545892
vhost->scsi_scrqs.scrqs = NULL;
58555893
vhost->scsi_scrqs.active_queues = 0;
58565894
vhost->do_enquiry = 0;
5857-
break;
5895+
vhost->mq_enabled = 0;
5896+
return;
58585897
}
58595898
}
58605899

5900+
ibmvfc_reg_sub_crqs(vhost);
5901+
58615902
LEAVE;
58625903
}
58635904

58645905
static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost)
58655906
{
5907+
struct ibmvfc_queue *scrq;
58665908
int i;
58675909

58685910
ENTER;
58695911
if (!vhost->scsi_scrqs.scrqs)
58705912
return;
58715913

5872-
for (i = 0; i < nr_scsi_hw_queues; i++)
5873-
ibmvfc_deregister_scsi_channel(vhost, i);
5914+
ibmvfc_dereg_sub_crqs(vhost);
5915+
5916+
for (i = 0; i < nr_scsi_hw_queues; i++) {
5917+
scrq = &vhost->scsi_scrqs.scrqs[i];
5918+
ibmvfc_free_queue(vhost, scrq);
5919+
}
58745920

58755921
kfree(vhost->scsi_scrqs.scrqs);
58765922
vhost->scsi_scrqs.scrqs = NULL;

drivers/scsi/ibmvscsi/ibmvfc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,7 @@ struct ibmvfc_queue {
789789
spinlock_t _lock;
790790
spinlock_t *q_lock;
791791

792+
struct ibmvfc_host *vhost;
792793
struct ibmvfc_event_pool evt_pool;
793794
struct list_head sent;
794795
struct list_head free;
@@ -797,7 +798,6 @@ struct ibmvfc_queue {
797798
union ibmvfc_iu cancel_rsp;
798799

799800
/* Sub-CRQ fields */
800-
struct ibmvfc_host *vhost;
801801
unsigned long cookie;
802802
unsigned long vios_cookie;
803803
unsigned long hw_irq;

drivers/scsi/scsi_debug.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2826,6 +2826,24 @@ static void zbc_open_zone(struct sdebug_dev_info *devip,
28262826
}
28272827
}
28282828

2829+
static inline void zbc_set_zone_full(struct sdebug_dev_info *devip,
2830+
struct sdeb_zone_state *zsp)
2831+
{
2832+
switch (zsp->z_cond) {
2833+
case ZC2_IMPLICIT_OPEN:
2834+
devip->nr_imp_open--;
2835+
break;
2836+
case ZC3_EXPLICIT_OPEN:
2837+
devip->nr_exp_open--;
2838+
break;
2839+
default:
2840+
WARN_ONCE(true, "Invalid zone %llu condition %x\n",
2841+
zsp->z_start, zsp->z_cond);
2842+
break;
2843+
}
2844+
zsp->z_cond = ZC5_FULL;
2845+
}
2846+
28292847
static void zbc_inc_wp(struct sdebug_dev_info *devip,
28302848
unsigned long long lba, unsigned int num)
28312849
{
@@ -2838,7 +2856,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip,
28382856
if (zsp->z_type == ZBC_ZTYPE_SWR) {
28392857
zsp->z_wp += num;
28402858
if (zsp->z_wp >= zend)
2841-
zsp->z_cond = ZC5_FULL;
2859+
zbc_set_zone_full(devip, zsp);
28422860
return;
28432861
}
28442862

@@ -2857,7 +2875,7 @@ static void zbc_inc_wp(struct sdebug_dev_info *devip,
28572875
n = num;
28582876
}
28592877
if (zsp->z_wp >= zend)
2860-
zsp->z_cond = ZC5_FULL;
2878+
zbc_set_zone_full(devip, zsp);
28612879

28622880
num -= n;
28632881
lba += n;

drivers/scsi/scsi_transport_iscsi.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,12 @@ iscsi_create_endpoint(int dd_size)
212212
return NULL;
213213

214214
mutex_lock(&iscsi_ep_idr_mutex);
215-
id = idr_alloc(&iscsi_ep_idr, ep, 0, -1, GFP_NOIO);
215+
216+
/*
217+
* First endpoint id should be 1 to comply with user space
218+
* applications (iscsid).
219+
*/
220+
id = idr_alloc(&iscsi_ep_idr, ep, 1, -1, GFP_NOIO);
216221
if (id < 0) {
217222
mutex_unlock(&iscsi_ep_idr_mutex);
218223
printk(KERN_ERR "Could not allocate endpoint ID. Error %d.\n",

drivers/scsi/storvsc_drv.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,7 +1844,7 @@ static struct scsi_host_template scsi_driver = {
18441844
.cmd_per_lun = 2048,
18451845
.this_id = -1,
18461846
/* Ensure there are no gaps in presented sgls */
1847-
.virt_boundary_mask = PAGE_SIZE-1,
1847+
.virt_boundary_mask = HV_HYP_PAGE_SIZE - 1,
18481848
.no_write_same = 1,
18491849
.track_queue_depth = 1,
18501850
.change_queue_depth = storvsc_change_queue_depth,
@@ -1895,6 +1895,7 @@ static int storvsc_probe(struct hv_device *device,
18951895
int target = 0;
18961896
struct storvsc_device *stor_device;
18971897
int max_sub_channels = 0;
1898+
u32 max_xfer_bytes;
18981899

18991900
/*
19001901
* We support sub-channels for storage on SCSI and FC controllers.
@@ -1968,12 +1969,28 @@ static int storvsc_probe(struct hv_device *device,
19681969
}
19691970
/* max cmd length */
19701971
host->max_cmd_len = STORVSC_MAX_CMD_LEN;
1971-
19721972
/*
1973-
* set the table size based on the info we got
1974-
* from the host.
1973+
* Any reasonable Hyper-V configuration should provide
1974+
* max_transfer_bytes value aligning to HV_HYP_PAGE_SIZE,
1975+
* protecting it from any weird value.
1976+
*/
1977+
max_xfer_bytes = round_down(stor_device->max_transfer_bytes, HV_HYP_PAGE_SIZE);
1978+
/* max_hw_sectors_kb */
1979+
host->max_sectors = max_xfer_bytes >> 9;
1980+
/*
1981+
* There are 2 requirements for Hyper-V storvsc sgl segments,
1982+
* based on which the below calculation for max segments is
1983+
* done:
1984+
*
1985+
* 1. Except for the first and last sgl segment, all sgl segments
1986+
* should be align to HV_HYP_PAGE_SIZE, that also means the
1987+
* maximum number of segments in a sgl can be calculated by
1988+
* dividing the total max transfer length by HV_HYP_PAGE_SIZE.
1989+
*
1990+
* 2. Except for the first and last, each entry in the SGL must
1991+
* have an offset that is a multiple of HV_HYP_PAGE_SIZE.
19751992
*/
1976-
host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT);
1993+
host->sg_tablesize = (max_xfer_bytes >> HV_HYP_PAGE_SHIFT) + 1;
19771994
/*
19781995
* For non-IDE disks, the host supports multiple channels.
19791996
* Set the number of HW queues we are supporting.

0 commit comments

Comments
 (0)