[PATCH 3/6] scsi: clean up S/G table freeing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Now that we are using the split completion model for the legacy request
path as well we can use scsi_mq_free_sgtables unconditionally.

Rename it to scsi_free_sgtables, use it for the legacy path and remove
scsi_release_(bidi_)buffers.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 drivers/scsi/scsi_lib.c | 77 +++++++++++++------------------------------------
 1 file changed, 20 insertions(+), 57 deletions(-)

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 1a3546e8..a737032 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -622,7 +622,7 @@ static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
 	}
 }
 
-static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd)
+static void scsi_free_sgtables(struct scsi_cmnd *cmd)
 {
 	if (cmd->sdb.table.nents)
 		scsi_free_sgtable(&cmd->sdb, true);
@@ -638,7 +638,6 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
 	struct Scsi_Host *shost = sdev->host;
 	unsigned long flags;
 
-	scsi_mq_free_sgtables(cmd);
 	scsi_uninit_cmd(cmd);
 
 	if (shost->use_cmd_list) {
@@ -649,42 +648,6 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
 	}
 }
 
-/*
- * Function:    scsi_release_buffers()
- *
- * Purpose:     Free resources allocate for a scsi_command.
- *
- * Arguments:   cmd	- command that we are bailing.
- *
- * Lock status: Assumed that no lock is held upon entry.
- *
- * Returns:     Nothing
- *
- * Notes:       In the event that an upper level driver rejects a
- *		command, we must release resources allocated during
- *		the __init_io() function.  Primarily this would involve
- *		the scatter-gather table.
- */
-static void scsi_release_buffers(struct scsi_cmnd *cmd)
-{
-	if (cmd->sdb.table.nents)
-		scsi_free_sgtable(&cmd->sdb, false);
-
-	memset(&cmd->sdb, 0, sizeof(cmd->sdb));
-
-	if (scsi_prot_sg_count(cmd))
-		scsi_free_sgtable(cmd->prot_sdb, false);
-}
-
-static void scsi_release_bidi_buffers(struct scsi_cmnd *cmd)
-{
-	struct scsi_data_buffer *bidi_sdb = cmd->request->next_rq->special;
-
-	scsi_free_sgtable(bidi_sdb, false);
-	kmem_cache_free(scsi_sdb_cache, bidi_sdb);
-	cmd->request->next_rq->special = NULL;
-}
-
 static bool scsi_end_request(struct request *req, int error,
 		unsigned int bytes, unsigned int bidi_bytes)
 {
@@ -703,16 +666,14 @@ static bool scsi_end_request(struct request *req, int error,
 	if (blk_queue_add_random(q))
 		add_disk_randomness(req->rq_disk);
 
+	/*
+	 * In the MQ case the command gets freed by __blk_mq_end_io, so we have
+	 * to do all cleanup that depends on the command before that.
+	 */
+	scsi_free_sgtables(cmd);
+
 	if (req->mq_ctx) {
-		/*
-		 * In the MQ case the command gets freed by __blk_mq_end_request,
-		 * so we have to do all cleanup that depends on it earlier.
-		 *
-		 * We also can't kick the queues from irq context, so we
-		 * will have to defer it to a workqueue.
-		 */
 		scsi_mq_uninit_cmd(cmd);
-
 		__blk_mq_end_request(req, error);
 
 		if (scsi_target(sdev)->single_lun ||
@@ -723,15 +684,15 @@ static bool scsi_end_request(struct request *req, int error,
 	} else {
 		unsigned long flags;
 
-		if (bidi_bytes)
-			scsi_release_bidi_buffers(cmd);
+		if (bidi_bytes) {
+			kmem_cache_free(scsi_sdb_cache, req->next_rq->special);
+			req->next_rq->special = NULL;
+		}
 
 		spin_lock_irqsave(q->queue_lock, flags);
 		blk_finish_request(req, error);
 		spin_unlock_irqrestore(q->queue_lock, flags);
 
-		scsi_release_buffers(cmd);
-
 		scsi_put_command(cmd);
 		scsi_run_queue(q);
 	}
@@ -1057,12 +1018,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 		/* Unprep the request and put it back at the head of the queue.
 		 * A new command will be prepared and issued.
 		 */
+		scsi_free_sgtables(cmd);
 		if (q->mq_ops) {
 			cmd->request->cmd_flags &= ~REQ_DONTPREP;
 			scsi_mq_uninit_cmd(cmd);
 			scsi_mq_requeue_cmd(cmd);
 		} else {
-			scsi_release_buffers(cmd);
 			scsi_requeue_command(q, cmd);
 		}
 		break;
@@ -1165,10 +1126,8 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask)
 
 	return BLKPREP_OK;
 err_exit:
-	if (is_mq) {
-		scsi_mq_free_sgtables(cmd);
-	} else {
-		scsi_release_buffers(cmd);
+	scsi_free_sgtables(cmd);
+	if (!is_mq) {
 		cmd->request->special = NULL;
 		scsi_put_command(cmd);
 		put_device(&sdev->sdev_gendev);
@@ -1338,7 +1297,9 @@ scsi_prep_return(struct request_queue *q, struct request *req, int ret)
 		/* release the command and kill it */
 		if (req->special) {
 			struct scsi_cmnd *cmd = req->special;
-			scsi_release_buffers(cmd);
+
+			scsi_free_sgtables(cmd);
+
 			scsi_put_command(cmd);
 			put_device(&sdev->sdev_gendev);
 			req->special = NULL;
@@ -1938,8 +1899,10 @@ out:
 		 * we hit an error, as we will never see this command
 		 * again.
 		 */
-		if (req->cmd_flags & REQ_DONTPREP)
+		if (req->cmd_flags & REQ_DONTPREP) {
+			scsi_free_sgtables(cmd);
 			scsi_mq_uninit_cmd(cmd);
+		}
 		break;
 	default:
 		break;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux