Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: esp: use sg helper to iterate over scatterlist

Unlike the legacy I/O path, scsi-mq preallocates a large array to hold
the scatterlist for each request. This static allocation can consume
substantial amounts of memory on modern controllers which support a
large number of concurrently outstanding requests.

To facilitate a switch to a smaller static allocation combined with a
dynamic allocation for requests that need it, we need to make sure all
SCSI drivers handle chained scatterlists correctly.

Convert remaining drivers that directly dereference the scatterlist
array to using the iterator functions.

[mkp: clarified commit message]

Cc: Christoph Hellwig <hch@lst.de>
Cc: Bart Van Assche <bvanassche@acm.org>
Cc: Ewan D. Milne <emilne@redhat.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Finn Thain <fthain@telegraphics.com.au>
Cc: Guenter Roeck <linux@roeck-us.net>
Reported-by: Guenter Roeck <linux@roeck-us.net>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Ming Lei and committed by
Martin K. Petersen
ee5a1dbf 0e9fdd2b

+15 -7
+13 -7
drivers/scsi/esp_scsi.c
··· 370 370 struct esp_cmd_priv *spriv = ESP_CMD_PRIV(cmd); 371 371 struct scatterlist *sg = scsi_sglist(cmd); 372 372 int total = 0, i; 373 + struct scatterlist *s; 373 374 374 375 if (cmd->sc_data_direction == DMA_NONE) 375 376 return; ··· 381 380 * a dma address, so perform an identity mapping. 382 381 */ 383 382 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]); 383 + 384 + scsi_for_each_sg(cmd, s, spriv->num_sg, i) { 385 + s->dma_address = (uintptr_t)sg_virt(s); 386 + total += sg_dma_len(s); 387 387 } 388 388 } else { 389 389 spriv->num_sg = scsi_dma_map(cmd); 390 - for (i = 0; i < spriv->num_sg; i++) 391 - total += sg_dma_len(&sg[i]); 390 + scsi_for_each_sg(cmd, s, spriv->num_sg, i) 391 + total += sg_dma_len(s); 392 392 } 393 393 spriv->cur_residue = sg_dma_len(sg); 394 + spriv->prv_sg = NULL; 394 395 spriv->cur_sg = sg; 395 396 spriv->tot_residue = total; 396 397 } ··· 446 443 p->tot_residue = 0; 447 444 } 448 445 if (!p->cur_residue && p->tot_residue) { 449 - p->cur_sg++; 446 + p->prv_sg = p->cur_sg; 447 + p->cur_sg = sg_next(p->cur_sg); 450 448 p->cur_residue = sg_dma_len(p->cur_sg); 451 449 } 452 450 } ··· 468 464 return; 469 465 } 470 466 ent->saved_cur_residue = spriv->cur_residue; 467 + ent->saved_prv_sg = spriv->prv_sg; 471 468 ent->saved_cur_sg = spriv->cur_sg; 472 469 ent->saved_tot_residue = spriv->tot_residue; 473 470 } ··· 483 478 return; 484 479 } 485 480 spriv->cur_residue = ent->saved_cur_residue; 481 + spriv->prv_sg = ent->saved_prv_sg; 486 482 spriv->cur_sg = ent->saved_cur_sg; 487 483 spriv->tot_residue = ent->saved_tot_residue; 488 484 } ··· 1652 1646 spriv = ESP_CMD_PRIV(ent->cmd); 1653 1647 1654 1648 if (spriv->cur_residue == sg_dma_len(spriv->cur_sg)) { 1655 - spriv->cur_sg--; 1649 + spriv->cur_sg = spriv->prv_sg; 1656 1650 spriv->cur_residue = 1; 1657 1651 } else 1658 1652 spriv->cur_residue++;
+2
drivers/scsi/esp_scsi.h
··· 251 251 struct esp_cmd_priv { 252 252 int num_sg; 253 253 int cur_residue; 254 + struct scatterlist *prv_sg; 254 255 struct scatterlist *cur_sg; 255 256 int tot_residue; 256 257 }; ··· 274 273 struct scsi_cmnd *cmd; 275 274 276 275 unsigned int saved_cur_residue; 276 + struct scatterlist *saved_prv_sg; 277 277 struct scatterlist *saved_cur_sg; 278 278 unsigned int saved_tot_residue; 279 279