Skip to content

Commit 92524fa

Browse files
Ming Leimartinkpetersen
authored andcommitted
scsi: core: avoid preallocating big SGL for protection information
scsi_mq_setup_tags() currently preallocates a big buffer for protection SGL entries. scsi_mq_sgl_size() is used to determine the size for both data and protection information scatterlists but the protection buffer is usually much smaller. For example, one 512-byte sector needs 8 bytes of protection information. Given that the maximum number of sectors for one request is 2560 (BLK_DEF_MAX_SECTORS) sectors, the max protection information buffer size is just 20K. The protection information segment count generally matches the number of bios in the request. As a result, the typical actual number of segments won't be very big. And should the need arise, allocating a bigger SGL from slab is fast enough. Pre-allocate only one SGL entry for protection information and switch to runtime allocation in case that the protection information segment number is bigger than 1. This reduces memory tied up by static command allocations. For example, 500+ MB is saved on single lpfc HBA. [mkp: attempted to clarify commit desc] Cc: Christoph Hellwig <[email protected]> Cc: Bart Van Assche <[email protected]> Cc: Ewan D. Milne <[email protected]> Cc: Hannes Reinecke <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Ming Lei <[email protected]> Reviewed-by: Bart Van Assche <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 4635873 commit 92524fa

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

drivers/scsi/scsi_lib.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939
#include "scsi_priv.h"
4040
#include "scsi_logging.h"
4141

42+
/*
43+
* Size of integrity metadata is usually small, 1 inline sg should
44+
* cover normal cases.
45+
*/
46+
#define SCSI_INLINE_PROT_SG_CNT 1
47+
4248
static struct kmem_cache *scsi_sdb_cache;
4349
static struct kmem_cache *scsi_sense_cache;
4450
static struct kmem_cache *scsi_sense_isadma_cache;
@@ -543,7 +549,8 @@ static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd)
543549
if (cmd->sdb.table.nents)
544550
sg_free_table_chained(&cmd->sdb.table, SG_CHUNK_SIZE);
545551
if (scsi_prot_sg_count(cmd))
546-
sg_free_table_chained(&cmd->prot_sdb->table, SG_CHUNK_SIZE);
552+
sg_free_table_chained(&cmd->prot_sdb->table,
553+
SCSI_INLINE_PROT_SG_CNT);
547554
}
548555

549556
static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
@@ -1032,7 +1039,7 @@ blk_status_t scsi_init_io(struct scsi_cmnd *cmd)
10321039

10331040
if (sg_alloc_table_chained(&prot_sdb->table, ivecs,
10341041
prot_sdb->table.sgl,
1035-
SG_CHUNK_SIZE)) {
1042+
SCSI_INLINE_PROT_SG_CNT)) {
10361043
ret = BLK_STS_RESOURCE;
10371044
goto out_free_sgtables;
10381045
}
@@ -1824,7 +1831,8 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
18241831
sgl_size = scsi_mq_sgl_size(shost);
18251832
cmd_size = sizeof(struct scsi_cmnd) + shost->hostt->cmd_size + sgl_size;
18261833
if (scsi_host_get_prot(shost))
1827-
cmd_size += sizeof(struct scsi_data_buffer) + sgl_size;
1834+
cmd_size += sizeof(struct scsi_data_buffer) +
1835+
sizeof(struct scatterlist) * SCSI_INLINE_PROT_SG_CNT;
18281836

18291837
memset(&shost->tag_set, 0, sizeof(shost->tag_set));
18301838
shost->tag_set.ops = &scsi_mq_ops;

0 commit comments

Comments
 (0)