Merge tag 'scsi-sg' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[platform/kernel/linux-rpi.git] / drivers / scsi / scsi_lib.c
index a2fa314..e1da8c7 100644 (file)
 #include "scsi_priv.h"
 #include "scsi_logging.h"
 
+/*
+ * Size of integrity metadata is usually small, 1 inline sg should
+ * cover normal cases.
+ */
+#ifdef CONFIG_ARCH_NO_SG_CHAIN
+#define  SCSI_INLINE_PROT_SG_CNT  0
+#define  SCSI_INLINE_SG_CNT  0
+#else
+#define  SCSI_INLINE_PROT_SG_CNT  1
+#define  SCSI_INLINE_SG_CNT  2
+#endif
+
 static struct kmem_cache *scsi_sdb_cache;
 static struct kmem_cache *scsi_sense_cache;
 static struct kmem_cache *scsi_sense_isadma_cache;
@@ -542,9 +554,11 @@ static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
 static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd)
 {
        if (cmd->sdb.table.nents)
-               sg_free_table_chained(&cmd->sdb.table, true);
+               sg_free_table_chained(&cmd->sdb.table,
+                               SCSI_INLINE_SG_CNT);
        if (scsi_prot_sg_count(cmd))
-               sg_free_table_chained(&cmd->prot_sdb->table, true);
+               sg_free_table_chained(&cmd->prot_sdb->table,
+                               SCSI_INLINE_PROT_SG_CNT);
 }
 
 static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
@@ -977,7 +991,8 @@ static blk_status_t scsi_init_sgtable(struct request *req,
         * If sg table allocation fails, requeue request later.
         */
        if (unlikely(sg_alloc_table_chained(&sdb->table,
-                       blk_rq_nr_phys_segments(req), sdb->table.sgl)))
+                       blk_rq_nr_phys_segments(req), sdb->table.sgl,
+                       SCSI_INLINE_SG_CNT)))
                return BLK_STS_RESOURCE;
 
        /* 
@@ -1031,7 +1046,8 @@ blk_status_t scsi_init_io(struct scsi_cmnd *cmd)
                ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio);
 
                if (sg_alloc_table_chained(&prot_sdb->table, ivecs,
-                               prot_sdb->table.sgl)) {
+                               prot_sdb->table.sgl,
+                               SCSI_INLINE_PROT_SG_CNT)) {
                        ret = BLK_STS_RESOURCE;
                        goto out_free_sgtables;
                }
@@ -1542,9 +1558,9 @@ static int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
 }
 
 /* Size in bytes of the sg-list stored in the scsi-mq command-private data. */
-static unsigned int scsi_mq_sgl_size(struct Scsi_Host *shost)
+static unsigned int scsi_mq_inline_sgl_size(struct Scsi_Host *shost)
 {
-       return min_t(unsigned int, shost->sg_tablesize, SG_CHUNK_SIZE) *
+       return min_t(unsigned int, shost->sg_tablesize, SCSI_INLINE_SG_CNT) *
                sizeof(struct scatterlist);
 }
 
@@ -1726,7 +1742,7 @@ static int scsi_mq_init_request(struct blk_mq_tag_set *set, struct request *rq,
        if (scsi_host_get_prot(shost)) {
                sg = (void *)cmd + sizeof(struct scsi_cmnd) +
                        shost->hostt->cmd_size;
-               cmd->prot_sdb = (void *)sg + scsi_mq_sgl_size(shost);
+               cmd->prot_sdb = (void *)sg + scsi_mq_inline_sgl_size(shost);
        }
 
        return 0;
@@ -1820,10 +1836,11 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
 {
        unsigned int cmd_size, sgl_size;
 
-       sgl_size = scsi_mq_sgl_size(shost);
+       sgl_size = scsi_mq_inline_sgl_size(shost);
        cmd_size = sizeof(struct scsi_cmnd) + shost->hostt->cmd_size + sgl_size;
        if (scsi_host_get_prot(shost))
-               cmd_size += sizeof(struct scsi_data_buffer) + sgl_size;
+               cmd_size += sizeof(struct scsi_data_buffer) +
+                       sizeof(struct scatterlist) * SCSI_INLINE_PROT_SG_CNT;
 
        memset(&shost->tag_set, 0, sizeof(shost->tag_set));
        shost->tag_set.ops = &scsi_mq_ops;