Commit 1f7563f7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
  ...
parents ba6d10ab 3e99b3b1
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -2112,7 +2112,8 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,

	freq->sg_table.sgl = freq->first_sgl;
	ret = sg_alloc_table_chained(&freq->sg_table,
			blk_rq_nr_phys_segments(rq), freq->sg_table.sgl);
			blk_rq_nr_phys_segments(rq), freq->sg_table.sgl,
			SG_CHUNK_SIZE);
	if (ret)
		return -ENOMEM;

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

	nvme_cleanup_cmd(rq);

	sg_free_table_chained(&freq->sg_table, true);
	sg_free_table_chained(&freq->sg_table, SG_CHUNK_SIZE);

	freq->sg_cnt = 0;
}
+4 −3
Original line number Diff line number Diff line
@@ -1144,7 +1144,7 @@ static void nvme_rdma_unmap_data(struct nvme_rdma_queue *queue,
				    WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);

	nvme_cleanup_cmd(rq);
	sg_free_table_chained(&req->sg_table, true);
	sg_free_table_chained(&req->sg_table, SG_CHUNK_SIZE);
}

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,

	req->sg_table.sgl = req->first_sgl;
	ret = sg_alloc_table_chained(&req->sg_table,
			blk_rq_nr_phys_segments(rq), req->sg_table.sgl);
			blk_rq_nr_phys_segments(rq), req->sg_table.sgl,
			SG_CHUNK_SIZE);
	if (ret)
		return -ENOMEM;

@@ -1299,7 +1300,7 @@ out_unmap_sg:
			req->nents, rq_data_dir(rq) ==
			WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
out_free_table:
	sg_free_table_chained(&req->sg_table, true);
	sg_free_table_chained(&req->sg_table, SG_CHUNK_SIZE);
	return ret;
}

+2 −2
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ static void nvme_loop_complete_rq(struct request *req)
	struct nvme_loop_iod *iod = blk_mq_rq_to_pdu(req);

	nvme_cleanup_cmd(req);
	sg_free_table_chained(&iod->sg_table, true);
	sg_free_table_chained(&iod->sg_table, SG_CHUNK_SIZE);
	nvme_complete_rq(req);
}

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

		iod->req.sg = iod->sg_table.sgl;
+2 −2
Original line number Diff line number Diff line
@@ -620,7 +620,7 @@ static void zfcp_fc_sg_free_table(struct scatterlist *sg, int count)
{
	int i;

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

	sg_init_table(sg, count);
	for (i = 0; i < count; i++, sg++) {
	for (i = 0; i < count; i++, sg = sg_next(sg)) {
		addr = (void *) get_zeroed_page(GFP_KERNEL);
		if (!addr) {
			zfcp_fc_sg_free_table(sg, i);
+18 −23
Original line number Diff line number Diff line
@@ -149,12 +149,10 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)

	if (scsi_bufflen(cmd)) {
		cmd->SCp.buffer = scsi_sglist(cmd);
		cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
		cmd->SCp.this_residual = cmd->SCp.buffer->length;
	} else {
		cmd->SCp.buffer = NULL;
		cmd->SCp.buffers_residual = 0;
		cmd->SCp.ptr = NULL;
		cmd->SCp.this_residual = 0;
	}
@@ -163,6 +161,17 @@ static inline void initialize_SCp(struct scsi_cmnd *cmd)
	cmd->SCp.Message = 0;
}

static inline void advance_sg_buffer(struct scsi_cmnd *cmd)
{
	struct scatterlist *s = cmd->SCp.buffer;

	if (!cmd->SCp.this_residual && s && !sg_is_last(s)) {
		cmd->SCp.buffer = sg_next(s);
		cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
		cmd->SCp.this_residual = cmd->SCp.buffer->length;
	}
}

/**
 * NCR5380_poll_politely2 - wait for two chip register values
 * @hostdata: host private data
@@ -1670,12 +1679,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
			    sun3_dma_setup_done != cmd) {
				int count;

				if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
					++cmd->SCp.buffer;
					--cmd->SCp.buffers_residual;
					cmd->SCp.this_residual = cmd->SCp.buffer->length;
					cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
				}
				advance_sg_buffer(cmd);

				count = sun3scsi_dma_xfer_len(hostdata, cmd);

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

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

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

		if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
			++tmp->SCp.buffer;
			--tmp->SCp.buffers_residual;
			tmp->SCp.this_residual = tmp->SCp.buffer->length;
			tmp->SCp.ptr = sg_virt(tmp->SCp.buffer);
		}
		advance_sg_buffer(tmp);

		count = sun3scsi_dma_xfer_len(hostdata, tmp);

Loading