Skip to content

Commit 1f7563f

Browse files
committed
Merge tag 'scsi-sg' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI scatter-gather list updates from James Bottomley: "This topic branch covers a fundamental change in how our sg lists are allocated to make mq more efficient by reducing the size of the preallocated sg list. This necessitates a large number of driver changes because the previous guarantee that if a driver specified SG_ALL as the size of its scatter list, it would get a non-chained list and didn't need to bother with scatterlist iterators is now broken and every driver *must* use scatterlist iterators. This was broken out as a separate topic because we need to convert all the drivers before pulling the trigger and unconverted drivers kept being found, necessitating a rebase" * tag 'scsi-sg' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (21 commits) scsi: core: don't preallocate small SGL in case of NO_SG_CHAIN scsi: lib/sg_pool.c: clear 'first_chunk' in case of no preallocation scsi: core: avoid preallocating big SGL for data scsi: core: avoid preallocating big SGL for protection information scsi: lib/sg_pool.c: improve APIs for allocating sg pool scsi: esp: use sg helper to iterate over scatterlist scsi: NCR5380: use sg helper to iterate over scatterlist scsi: wd33c93: use sg helper to iterate over scatterlist scsi: ppa: use sg helper to iterate over scatterlist scsi: pcmcia: nsp_cs: use sg helper to iterate over scatterlist scsi: imm: use sg helper to iterate over scatterlist scsi: aha152x: use sg helper to iterate over scatterlist scsi: s390: zfcp_fc: use sg helper to iterate over scatterlist scsi: staging: unisys: visorhba: use sg helper to iterate over scatterlist scsi: usb: image: microtek: use sg helper to iterate over scatterlist scsi: pmcraid: use sg helper to iterate over scatterlist scsi: ipr: use sg helper to iterate over scatterlist scsi: mvumi: use sg helper to iterate over scatterlist scsi: lpfc: use sg helper to iterate over scatterlist scsi: advansys: use sg helper to iterate over scatterlist ...
2 parents ba6d10a + 3e99b3b commit 1f7563f

File tree

26 files changed

+205
-154
lines changed

26 files changed

+205
-154
lines changed

drivers/nvme/host/fc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,7 +2112,8 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
21122112

21132113
freq->sg_table.sgl = freq->first_sgl;
21142114
ret = sg_alloc_table_chained(&freq->sg_table,
2115-
blk_rq_nr_phys_segments(rq), freq->sg_table.sgl);
2115+
blk_rq_nr_phys_segments(rq), freq->sg_table.sgl,
2116+
SG_CHUNK_SIZE);
21162117
if (ret)
21172118
return -ENOMEM;
21182119

@@ -2122,7 +2123,7 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
21222123
freq->sg_cnt = fc_dma_map_sg(ctrl->lport->dev, freq->sg_table.sgl,
21232124
op->nents, dir);
21242125
if (unlikely(freq->sg_cnt <= 0)) {
2125-
sg_free_table_chained(&freq->sg_table, true);
2126+
sg_free_table_chained(&freq->sg_table, SG_CHUNK_SIZE);
21262127
freq->sg_cnt = 0;
21272128
return -EFAULT;
21282129
}
@@ -2148,7 +2149,7 @@ nvme_fc_unmap_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
21482149

21492150
nvme_cleanup_cmd(rq);
21502151

2151-
sg_free_table_chained(&freq->sg_table, true);
2152+
sg_free_table_chained(&freq->sg_table, SG_CHUNK_SIZE);
21522153

21532154
freq->sg_cnt = 0;
21542155
}

drivers/nvme/host/rdma.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ static void nvme_rdma_unmap_data(struct nvme_rdma_queue *queue,
11441144
WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
11451145

11461146
nvme_cleanup_cmd(rq);
1147-
sg_free_table_chained(&req->sg_table, true);
1147+
sg_free_table_chained(&req->sg_table, SG_CHUNK_SIZE);
11481148
}
11491149

11501150
static int nvme_rdma_set_sg_null(struct nvme_command *c)
@@ -1259,7 +1259,8 @@ static int nvme_rdma_map_data(struct nvme_rdma_queue *queue,
12591259

12601260
req->sg_table.sgl = req->first_sgl;
12611261
ret = sg_alloc_table_chained(&req->sg_table,
1262-
blk_rq_nr_phys_segments(rq), req->sg_table.sgl);
1262+
blk_rq_nr_phys_segments(rq), req->sg_table.sgl,
1263+
SG_CHUNK_SIZE);
12631264
if (ret)
12641265
return -ENOMEM;
12651266

@@ -1299,7 +1300,7 @@ static int nvme_rdma_map_data(struct nvme_rdma_queue *queue,
12991300
req->nents, rq_data_dir(rq) ==
13001301
WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
13011302
out_free_table:
1302-
sg_free_table_chained(&req->sg_table, true);
1303+
sg_free_table_chained(&req->sg_table, SG_CHUNK_SIZE);
13031304
return ret;
13041305
}
13051306

drivers/nvme/target/loop.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static void nvme_loop_complete_rq(struct request *req)
7777
struct nvme_loop_iod *iod = blk_mq_rq_to_pdu(req);
7878

7979
nvme_cleanup_cmd(req);
80-
sg_free_table_chained(&iod->sg_table, true);
80+
sg_free_table_chained(&iod->sg_table, SG_CHUNK_SIZE);
8181
nvme_complete_rq(req);
8282
}
8383

@@ -157,7 +157,7 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx,
157157
iod->sg_table.sgl = iod->first_sgl;
158158
if (sg_alloc_table_chained(&iod->sg_table,
159159
blk_rq_nr_phys_segments(req),
160-
iod->sg_table.sgl))
160+
iod->sg_table.sgl, SG_CHUNK_SIZE))
161161
return BLK_STS_RESOURCE;
162162

163163
iod->req.sg = iod->sg_table.sgl;

drivers/s390/scsi/zfcp_fc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ static void zfcp_fc_sg_free_table(struct scatterlist *sg, int count)
620620
{
621621
int i;
622622

623-
for (i = 0; i < count; i++, sg++)
623+
for (i = 0; i < count; i++, sg = sg_next(sg))
624624
if (sg)
625625
free_page((unsigned long) sg_virt(sg));
626626
else
@@ -641,7 +641,7 @@ static int zfcp_fc_sg_setup_table(struct scatterlist *sg, int count)
641641
int i;
642642

643643
sg_init_table(sg, count);
644-
for (i = 0; i < count; i++, sg++) {
644+
for (i = 0; i < count; i++, sg = sg_next(sg)) {
645645
addr = (void *) get_zeroed_page(GFP_KERNEL);
646646
if (!addr) {
647647
zfcp_fc_sg_free_table(sg, i);

drivers/scsi/NCR5380.c

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,10 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
149149

150150
if (scsi_bufflen(cmd)) {
151151
cmd->SCp.buffer = scsi_sglist(cmd);
152-
cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
153152
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
154153
cmd->SCp.this_residual = cmd->SCp.buffer->length;
155154
} else {
156155
cmd->SCp.buffer = NULL;
157-
cmd->SCp.buffers_residual = 0;
158156
cmd->SCp.ptr = NULL;
159157
cmd->SCp.this_residual = 0;
160158
}
@@ -163,6 +161,17 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
163161
cmd->SCp.Message = 0;
164162
}
165163

164+
static inline void advance_sg_buffer(struct scsi_cmnd *cmd)
165+
{
166+
struct scatterlist *s = cmd->SCp.buffer;
167+
168+
if (!cmd->SCp.this_residual && s && !sg_is_last(s)) {
169+
cmd->SCp.buffer = sg_next(s);
170+
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
171+
cmd->SCp.this_residual = cmd->SCp.buffer->length;
172+
}
173+
}
174+
166175
/**
167176
* NCR5380_poll_politely2 - wait for two chip register values
168177
* @hostdata: host private data
@@ -1670,12 +1679,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
16701679
sun3_dma_setup_done != cmd) {
16711680
int count;
16721681

1673-
if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
1674-
++cmd->SCp.buffer;
1675-
--cmd->SCp.buffers_residual;
1676-
cmd->SCp.this_residual = cmd->SCp.buffer->length;
1677-
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
1678-
}
1682+
advance_sg_buffer(cmd);
16791683

16801684
count = sun3scsi_dma_xfer_len(hostdata, cmd);
16811685

@@ -1725,15 +1729,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
17251729
* scatter-gather list, move onto the next one.
17261730
*/
17271731

1728-
if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
1729-
++cmd->SCp.buffer;
1730-
--cmd->SCp.buffers_residual;
1731-
cmd->SCp.this_residual = cmd->SCp.buffer->length;
1732-
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
1733-
dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
1734-
cmd->SCp.this_residual,
1735-
cmd->SCp.buffers_residual);
1736-
}
1732+
advance_sg_buffer(cmd);
1733+
dsprintk(NDEBUG_INFORMATION, instance,
1734+
"this residual %d, sg ents %d\n",
1735+
cmd->SCp.this_residual,
1736+
sg_nents(cmd->SCp.buffer));
17371737

17381738
/*
17391739
* The preferred transfer method is going to be
@@ -2126,12 +2126,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
21262126
if (sun3_dma_setup_done != tmp) {
21272127
int count;
21282128

2129-
if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
2130-
++tmp->SCp.buffer;
2131-
--tmp->SCp.buffers_residual;
2132-
tmp->SCp.this_residual = tmp->SCp.buffer->length;
2133-
tmp->SCp.ptr = sg_virt(tmp->SCp.buffer);
2134-
}
2129+
advance_sg_buffer(tmp);
21352130

21362131
count = sun3scsi_dma_xfer_len(hostdata, tmp);
21372132

drivers/scsi/advansys.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7710,7 +7710,7 @@ adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp,
77107710
sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */
77117711
return ADV_SUCCESS;
77127712
}
7713-
slp++;
7713+
slp = sg_next(slp);
77147714
}
77157715
sg_block->sg_cnt = NO_OF_SG_PER_BLOCK;
77167716
prev_sg_block = sg_block;

drivers/scsi/aha152x.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -937,21 +937,18 @@ static int aha152x_internal_queue(struct scsi_cmnd *SCpnt,
937937
SCp.ptr : buffer pointer
938938
SCp.this_residual : buffer length
939939
SCp.buffer : next buffer
940-
SCp.buffers_residual : left buffers in list
941940
SCp.phase : current state of the command */
942941

943942
if ((phase & resetting) || !scsi_sglist(SCpnt)) {
944943
SCpnt->SCp.ptr = NULL;
945944
SCpnt->SCp.this_residual = 0;
946945
scsi_set_resid(SCpnt, 0);
947946
SCpnt->SCp.buffer = NULL;
948-
SCpnt->SCp.buffers_residual = 0;
949947
} else {
950948
scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
951949
SCpnt->SCp.buffer = scsi_sglist(SCpnt);
952950
SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer);
953951
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
954-
SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
955952
}
956953

957954
DO_LOCK(flags);
@@ -2019,10 +2016,9 @@ static void datai_run(struct Scsi_Host *shpnt)
20192016
}
20202017

20212018
if (CURRENT_SC->SCp.this_residual == 0 &&
2022-
CURRENT_SC->SCp.buffers_residual > 0) {
2019+
!sg_is_last(CURRENT_SC->SCp.buffer)) {
20232020
/* advance to next buffer */
2024-
CURRENT_SC->SCp.buffers_residual--;
2025-
CURRENT_SC->SCp.buffer++;
2021+
CURRENT_SC->SCp.buffer = sg_next(CURRENT_SC->SCp.buffer);
20262022
CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer);
20272023
CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
20282024
}
@@ -2125,10 +2121,10 @@ static void datao_run(struct Scsi_Host *shpnt)
21252121
CMD_INC_RESID(CURRENT_SC, -2 * data_count);
21262122
}
21272123

2128-
if(CURRENT_SC->SCp.this_residual==0 && CURRENT_SC->SCp.buffers_residual>0) {
2124+
if (CURRENT_SC->SCp.this_residual == 0 &&
2125+
!sg_is_last(CURRENT_SC->SCp.buffer)) {
21292126
/* advance to next buffer */
2130-
CURRENT_SC->SCp.buffers_residual--;
2131-
CURRENT_SC->SCp.buffer++;
2127+
CURRENT_SC->SCp.buffer = sg_next(CURRENT_SC->SCp.buffer);
21322128
CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer);
21332129
CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
21342130
}
@@ -2147,22 +2143,26 @@ static void datao_run(struct Scsi_Host *shpnt)
21472143
static void datao_end(struct Scsi_Host *shpnt)
21482144
{
21492145
if(TESTLO(DMASTAT, DFIFOEMP)) {
2150-
int data_count = (DATA_LEN - scsi_get_resid(CURRENT_SC)) -
2151-
GETSTCNT();
2146+
u32 datao_cnt = GETSTCNT();
2147+
int datao_out = DATA_LEN - scsi_get_resid(CURRENT_SC);
2148+
int done;
2149+
struct scatterlist *sg = scsi_sglist(CURRENT_SC);
21522150

2153-
CMD_INC_RESID(CURRENT_SC, data_count);
2151+
CMD_INC_RESID(CURRENT_SC, datao_out - datao_cnt);
21542152

2155-
data_count -= CURRENT_SC->SCp.ptr -
2156-
SG_ADDRESS(CURRENT_SC->SCp.buffer);
2157-
while(data_count>0) {
2158-
CURRENT_SC->SCp.buffer--;
2159-
CURRENT_SC->SCp.buffers_residual++;
2160-
data_count -= CURRENT_SC->SCp.buffer->length;
2153+
done = scsi_bufflen(CURRENT_SC) - scsi_get_resid(CURRENT_SC);
2154+
/* Locate the first SG entry not yet sent */
2155+
while (done > 0 && !sg_is_last(sg)) {
2156+
if (done < sg->length)
2157+
break;
2158+
done -= sg->length;
2159+
sg = sg_next(sg);
21612160
}
2162-
CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) -
2163-
data_count;
2164-
CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length +
2165-
data_count;
2161+
2162+
CURRENT_SC->SCp.buffer = sg;
2163+
CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) + done;
2164+
CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length -
2165+
done;
21662166
}
21672167

21682168
SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
@@ -2490,7 +2490,7 @@ static void get_command(struct seq_file *m, struct scsi_cmnd * ptr)
24902490

24912491
seq_printf(m, "); resid=%d; residual=%d; buffers=%d; phase |",
24922492
scsi_get_resid(ptr), ptr->SCp.this_residual,
2493-
ptr->SCp.buffers_residual);
2493+
sg_nents(ptr->SCp.buffer) - 1);
24942494

24952495
if (ptr->SCp.phase & not_issued)
24962496
seq_puts(m, "not issued|");

drivers/scsi/esp_scsi.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
371371
struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd);
372372
struct scatterlist *sg = scsi_sglist(cmd);
373373
int total = 0, i;
374+
struct scatterlist *s;
374375

375376
if (cmd->sc_data_direction == DMA_NONE)
376377
return;
@@ -381,16 +382,18 @@ static void esp_map_dma(struct esp *esp, struct scsi_cmnd *cmd)
381382
* a dma address, so perform an identity mapping.
382383
*/
383384
spriv->num_sg = scsi_sg_count(cmd);
384-
for (i = 0; i < spriv->num_sg; i++) {
385-
sg[i].dma_address = (uintptr_t)sg_virt(&sg[i]);
386-
total += sg_dma_len(&sg[i]);
385+
386+
scsi_for_each_sg(cmd, s, spriv->num_sg, i) {
387+
s->dma_address = (uintptr_t)sg_virt(s);
388+
total += sg_dma_len(s);
387389
}
388390
} else {
389391
spriv->num_sg = scsi_dma_map(cmd);
390-
for (i = 0; i < spriv->num_sg; i++)
391-
total += sg_dma_len(&sg[i]);
392+
scsi_for_each_sg(cmd, s, spriv->num_sg, i)
393+
total += sg_dma_len(s);
392394
}
393395
spriv->cur_residue = sg_dma_len(sg);
396+
spriv->prv_sg = NULL;
394397
spriv->cur_sg = sg;
395398
spriv->tot_residue = total;
396399
}
@@ -444,7 +447,8 @@ static void esp_advance_dma(struct esp *esp, struct esp_cmd_entry *ent,
444447
p->tot_residue = 0;
445448
}
446449
if (!p->cur_residue && p->tot_residue) {
447-
p->cur_sg++;
450+
p->prv_sg = p->cur_sg;
451+
p->cur_sg = sg_next(p->cur_sg);
448452
p->cur_residue = sg_dma_len(p->cur_sg);
449453
}
450454
}
@@ -465,6 +469,7 @@ static void esp_save_pointers(struct esp *esp, struct esp_cmd_entry *ent)
465469
return;
466470
}
467471
ent->saved_cur_residue = spriv->cur_residue;
472+
ent->saved_prv_sg = spriv->prv_sg;
468473
ent->saved_cur_sg = spriv->cur_sg;
469474
ent->saved_tot_residue = spriv->tot_residue;
470475
}
@@ -479,6 +484,7 @@ static void esp_restore_pointers(struct esp *esp, struct esp_cmd_entry *ent)
479484
return;
480485
}
481486
spriv->cur_residue = ent->saved_cur_residue;
487+
spriv->prv_sg = ent->saved_prv_sg;
482488
spriv->cur_sg = ent->saved_cur_sg;
483489
spriv->tot_residue = ent->saved_tot_residue;
484490
}
@@ -1647,7 +1653,7 @@ static int esp_msgin_process(struct esp *esp)
16471653
spriv = ESP_CMD_PRIV(ent->cmd);
16481654

16491655
if (spriv->cur_residue == sg_dma_len(spriv->cur_sg)) {
1650-
spriv->cur_sg--;
1656+
spriv->cur_sg = spriv->prv_sg;
16511657
spriv->cur_residue = 1;
16521658
} else
16531659
spriv->cur_residue++;

drivers/scsi/esp_scsi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@
251251
struct esp_cmd_priv {
252252
int num_sg;
253253
int cur_residue;
254+
struct scatterlist *prv_sg;
254255
struct scatterlist *cur_sg;
255256
int tot_residue;
256257
};
@@ -273,6 +274,7 @@ struct esp_cmd_entry {
273274
struct scsi_cmnd *cmd;
274275

275276
unsigned int saved_cur_residue;
277+
struct scatterlist *saved_prv_sg;
276278
struct scatterlist *saved_cur_sg;
277279
unsigned int saved_tot_residue;
278280

drivers/scsi/imm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
687687
if (cmd->SCp.buffer && !cmd->SCp.this_residual) {
688688
/* if scatter/gather, advance to the next segment */
689689
if (cmd->SCp.buffers_residual--) {
690-
cmd->SCp.buffer++;
690+
cmd->SCp.buffer = sg_next(cmd->SCp.buffer);
691691
cmd->SCp.this_residual =
692692
cmd->SCp.buffer->length;
693693
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);

0 commit comments

Comments
 (0)