Skip to content

Commit ad215aa

Browse files
bvanasschejgunthorpe
authored andcommitted
RDMA/srp: Make struct scsi_cmnd and struct srp_request adjacent
Define .init_cmd_priv and .exit_cmd_priv callback functions in struct scsi_host_template. Set .cmd_size such that the SCSI core allocates per-command private data. Use scsi_cmd_priv() to access that private data. Remove the req_ring pointer from struct srp_rdma_ch since it is no longer necessary. Convert srp_alloc_req_data() and srp_free_req_data() into functions that initialize one instance of the SRP-private command data. This is a micro-optimization since this patch removes several pointer dereferences from the hot path. Note: due to commit e73a5e8 ("scsi: core: Only return started requests from scsi_host_find_tag()"), it is no longer necessary to protect the completion path against duplicate responses. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bart Van Assche <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 7ec2e27 commit ad215aa

File tree

2 files changed

+63
-92
lines changed

2 files changed

+63
-92
lines changed

drivers/infiniband/ulp/srp/ib_srp.c

Lines changed: 63 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -965,67 +965,52 @@ static void srp_disconnect_target(struct srp_target_port *target)
965965
}
966966
}
967967

968-
static void srp_free_req_data(struct srp_target_port *target,
969-
struct srp_rdma_ch *ch)
968+
static int srp_exit_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
970969
{
970+
struct srp_target_port *target = host_to_target(shost);
971971
struct srp_device *dev = target->srp_host->srp_dev;
972972
struct ib_device *ibdev = dev->dev;
973-
struct srp_request *req;
974-
int i;
973+
struct srp_request *req = scsi_cmd_priv(cmd);
975974

976-
if (!ch->req_ring)
977-
return;
978-
979-
for (i = 0; i < target->req_ring_size; ++i) {
980-
req = &ch->req_ring[i];
981-
if (dev->use_fast_reg)
982-
kfree(req->fr_list);
983-
if (req->indirect_dma_addr) {
984-
ib_dma_unmap_single(ibdev, req->indirect_dma_addr,
985-
target->indirect_size,
986-
DMA_TO_DEVICE);
987-
}
988-
kfree(req->indirect_desc);
975+
kfree(req->fr_list);
976+
if (req->indirect_dma_addr) {
977+
ib_dma_unmap_single(ibdev, req->indirect_dma_addr,
978+
target->indirect_size,
979+
DMA_TO_DEVICE);
989980
}
981+
kfree(req->indirect_desc);
990982

991-
kfree(ch->req_ring);
992-
ch->req_ring = NULL;
983+
return 0;
993984
}
994985

995-
static int srp_alloc_req_data(struct srp_rdma_ch *ch)
986+
static int srp_init_cmd_priv(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
996987
{
997-
struct srp_target_port *target = ch->target;
988+
struct srp_target_port *target = host_to_target(shost);
998989
struct srp_device *srp_dev = target->srp_host->srp_dev;
999990
struct ib_device *ibdev = srp_dev->dev;
1000-
struct srp_request *req;
991+
struct srp_request *req = scsi_cmd_priv(cmd);
1001992
dma_addr_t dma_addr;
1002-
int i, ret = -ENOMEM;
993+
int ret = -ENOMEM;
1003994

1004-
ch->req_ring = kcalloc(target->req_ring_size, sizeof(*ch->req_ring),
1005-
GFP_KERNEL);
1006-
if (!ch->req_ring)
1007-
goto out;
1008-
1009-
for (i = 0; i < target->req_ring_size; ++i) {
1010-
req = &ch->req_ring[i];
1011-
if (srp_dev->use_fast_reg) {
1012-
req->fr_list = kmalloc_array(target->mr_per_cmd,
1013-
sizeof(void *), GFP_KERNEL);
1014-
if (!req->fr_list)
1015-
goto out;
1016-
}
1017-
req->indirect_desc = kmalloc(target->indirect_size, GFP_KERNEL);
1018-
if (!req->indirect_desc)
1019-
goto out;
1020-
1021-
dma_addr = ib_dma_map_single(ibdev, req->indirect_desc,
1022-
target->indirect_size,
1023-
DMA_TO_DEVICE);
1024-
if (ib_dma_mapping_error(ibdev, dma_addr))
995+
if (srp_dev->use_fast_reg) {
996+
req->fr_list = kmalloc_array(target->mr_per_cmd, sizeof(void *),
997+
GFP_KERNEL);
998+
if (!req->fr_list)
1025999
goto out;
1000+
}
1001+
req->indirect_desc = kmalloc(target->indirect_size, GFP_KERNEL);
1002+
if (!req->indirect_desc)
1003+
goto out;
10261004

1027-
req->indirect_dma_addr = dma_addr;
1005+
dma_addr = ib_dma_map_single(ibdev, req->indirect_desc,
1006+
target->indirect_size,
1007+
DMA_TO_DEVICE);
1008+
if (ib_dma_mapping_error(ibdev, dma_addr)) {
1009+
srp_exit_cmd_priv(shost, cmd);
1010+
goto out;
10281011
}
1012+
1013+
req->indirect_dma_addr = dma_addr;
10291014
ret = 0;
10301015

10311016
out:
@@ -1067,10 +1052,6 @@ static void srp_remove_target(struct srp_target_port *target)
10671052
}
10681053
cancel_work_sync(&target->tl_err_work);
10691054
srp_rport_put(target->rport);
1070-
for (i = 0; i < target->ch_count; i++) {
1071-
ch = &target->ch[i];
1072-
srp_free_req_data(target, ch);
1073-
}
10741055
kfree(target->ch);
10751056
target->ch = NULL;
10761057

@@ -1289,22 +1270,32 @@ static void srp_finish_req(struct srp_rdma_ch *ch, struct srp_request *req,
12891270
}
12901271
}
12911272

1292-
static void srp_terminate_io(struct srp_rport *rport)
1273+
struct srp_terminate_context {
1274+
struct srp_target_port *srp_target;
1275+
int scsi_result;
1276+
};
1277+
1278+
static bool srp_terminate_cmd(struct scsi_cmnd *scmnd, void *context_ptr,
1279+
bool reserved)
12931280
{
1294-
struct srp_target_port *target = rport->lld_data;
1295-
struct srp_rdma_ch *ch;
1296-
int i, j;
1281+
struct srp_terminate_context *context = context_ptr;
1282+
struct srp_target_port *target = context->srp_target;
1283+
u32 tag = blk_mq_unique_tag(scmnd->request);
1284+
struct srp_rdma_ch *ch = &target->ch[blk_mq_unique_tag_to_hwq(tag)];
1285+
struct srp_request *req = scsi_cmd_priv(scmnd);
12971286

1298-
for (i = 0; i < target->ch_count; i++) {
1299-
ch = &target->ch[i];
1287+
srp_finish_req(ch, req, NULL, context->scsi_result);
13001288

1301-
for (j = 0; j < target->req_ring_size; ++j) {
1302-
struct srp_request *req = &ch->req_ring[j];
1289+
return true;
1290+
}
13031291

1304-
srp_finish_req(ch, req, NULL,
1305-
DID_TRANSPORT_FAILFAST << 16);
1306-
}
1307-
}
1292+
static void srp_terminate_io(struct srp_rport *rport)
1293+
{
1294+
struct srp_target_port *target = rport->lld_data;
1295+
struct srp_terminate_context context = { .srp_target = target,
1296+
.scsi_result = DID_TRANSPORT_FAILFAST << 16 };
1297+
1298+
scsi_host_busy_iter(target->scsi_host, srp_terminate_cmd, &context);
13081299
}
13091300

13101301
/* Calculate maximum initiator to target information unit length. */
@@ -1360,13 +1351,12 @@ static int srp_rport_reconnect(struct srp_rport *rport)
13601351
ch = &target->ch[i];
13611352
ret += srp_new_cm_id(ch);
13621353
}
1363-
for (i = 0; i < target->ch_count; i++) {
1364-
ch = &target->ch[i];
1365-
for (j = 0; j < target->req_ring_size; ++j) {
1366-
struct srp_request *req = &ch->req_ring[j];
1354+
{
1355+
struct srp_terminate_context context = {
1356+
.srp_target = target, .scsi_result = DID_RESET << 16};
13671357

1368-
srp_finish_req(ch, req, NULL, DID_RESET << 16);
1369-
}
1358+
scsi_host_busy_iter(target->scsi_host, srp_terminate_cmd,
1359+
&context);
13701360
}
13711361
for (i = 0; i < target->ch_count; i++) {
13721362
ch = &target->ch[i];
@@ -1962,13 +1952,10 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp)
19621952
spin_unlock_irqrestore(&ch->lock, flags);
19631953
} else {
19641954
scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag);
1965-
if (scmnd && scmnd->host_scribble) {
1966-
req = (void *)scmnd->host_scribble;
1955+
if (scmnd) {
1956+
req = scsi_cmd_priv(scmnd);
19671957
scmnd = srp_claim_req(ch, req, NULL, scmnd);
19681958
} else {
1969-
scmnd = NULL;
1970-
}
1971-
if (!scmnd) {
19721959
shost_printk(KERN_ERR, target->scsi_host,
19731960
"Null scmnd for RSP w/tag %#016llx received on ch %td / QP %#x\n",
19741961
rsp->tag, ch - target->ch, ch->qp->qp_num);
@@ -2000,7 +1987,6 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp)
20001987
srp_free_req(ch, req, scmnd,
20011988
be32_to_cpu(rsp->req_lim_delta));
20021989

2003-
scmnd->host_scribble = NULL;
20041990
scmnd->scsi_done(scmnd);
20051991
}
20061992
}
@@ -2168,13 +2154,12 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
21682154
{
21692155
struct srp_target_port *target = host_to_target(shost);
21702156
struct srp_rdma_ch *ch;
2171-
struct srp_request *req;
2157+
struct srp_request *req = scsi_cmd_priv(scmnd);
21722158
struct srp_iu *iu;
21732159
struct srp_cmd *cmd;
21742160
struct ib_device *dev;
21752161
unsigned long flags;
21762162
u32 tag;
2177-
u16 idx;
21782163
int len, ret;
21792164

21802165
scmnd->result = srp_chkready(target->rport);
@@ -2184,10 +2169,6 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
21842169
WARN_ON_ONCE(scmnd->request->tag < 0);
21852170
tag = blk_mq_unique_tag(scmnd->request);
21862171
ch = &target->ch[blk_mq_unique_tag_to_hwq(tag)];
2187-
idx = blk_mq_unique_tag_to_tag(tag);
2188-
WARN_ONCE(idx >= target->req_ring_size, "%s: tag %#x: idx %d >= %d\n",
2189-
dev_name(&shost->shost_gendev), tag, idx,
2190-
target->req_ring_size);
21912172

21922173
spin_lock_irqsave(&ch->lock, flags);
21932174
iu = __srp_get_tx_iu(ch, SRP_IU_CMD);
@@ -2196,13 +2177,10 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
21962177
if (!iu)
21972178
goto err;
21982179

2199-
req = &ch->req_ring[idx];
22002180
dev = target->srp_host->srp_dev->dev;
22012181
ib_dma_sync_single_for_cpu(dev, iu->dma, ch->max_it_iu_len,
22022182
DMA_TO_DEVICE);
22032183

2204-
scmnd->host_scribble = (void *) req;
2205-
22062184
cmd = iu->buf;
22072185
memset(cmd, 0, sizeof *cmd);
22082186

@@ -3083,6 +3061,8 @@ static struct scsi_host_template srp_template = {
30833061
.target_alloc = srp_target_alloc,
30843062
.slave_configure = srp_slave_configure,
30853063
.info = srp_target_info,
3064+
.init_cmd_priv = srp_init_cmd_priv,
3065+
.exit_cmd_priv = srp_exit_cmd_priv,
30863066
.queuecommand = srp_queuecommand,
30873067
.change_queue_depth = srp_change_queue_depth,
30883068
.eh_timed_out = srp_timed_out,
@@ -3096,6 +3076,7 @@ static struct scsi_host_template srp_template = {
30963076
.cmd_per_lun = SRP_DEFAULT_CMD_SQ_SIZE,
30973077
.shost_attrs = srp_host_attrs,
30983078
.track_queue_depth = 1,
3079+
.cmd_size = sizeof(struct srp_request),
30993080
};
31003081

31013082
static int srp_sdev_count(struct Scsi_Host *host)
@@ -3675,8 +3656,6 @@ static ssize_t srp_create_target(struct device *dev,
36753656
if (ret)
36763657
goto out;
36773658

3678-
target->req_ring_size = target->queue_size - SRP_TSK_MGMT_SQ_SIZE;
3679-
36803659
if (!srp_conn_unique(target->srp_host, target)) {
36813660
if (target->using_rdma_cm) {
36823661
shost_printk(KERN_INFO, target->scsi_host,
@@ -3779,10 +3758,6 @@ static ssize_t srp_create_target(struct device *dev,
37793758
if (ret)
37803759
goto err_disconnect;
37813760

3782-
ret = srp_alloc_req_data(ch);
3783-
if (ret)
3784-
goto err_disconnect;
3785-
37863761
ret = srp_connect_ch(ch, max_iu_len, multich);
37873762
if (ret) {
37883763
char dst[64];
@@ -3801,7 +3776,6 @@ static ssize_t srp_create_target(struct device *dev,
38013776
goto free_ch;
38023777
} else {
38033778
srp_free_ch_ib(target, ch);
3804-
srp_free_req_data(target, ch);
38053779
target->ch_count = ch - target->ch;
38063780
goto connected;
38073781
}
@@ -3862,7 +3836,6 @@ static ssize_t srp_create_target(struct device *dev,
38623836
for (i = 0; i < target->ch_count; i++) {
38633837
ch = &target->ch[i];
38643838
srp_free_ch_ib(target, ch);
3865-
srp_free_req_data(target, ch);
38663839
}
38673840

38683841
kfree(target->ch);

drivers/infiniband/ulp/srp/ib_srp.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,6 @@ struct srp_rdma_ch {
174174

175175
struct srp_iu **tx_ring;
176176
struct srp_iu **rx_ring;
177-
struct srp_request *req_ring;
178177
int comp_vector;
179178

180179
u64 tsk_mgmt_tag;
@@ -220,7 +219,6 @@ struct srp_target_port {
220219
int mr_pool_size;
221220
int mr_per_cmd;
222221
int queue_size;
223-
int req_ring_size;
224222
int comp_vector;
225223
int tl_retry_count;
226224

0 commit comments

Comments
 (0)