[Stgt-devel] [Patch 3/4] (kernel) tgt_write process one entry

Robert Jennings rcj
Tue Oct 23 23:31:36 CEST 2007


The tgt_write operation will process only one target event when 
it is called rather than processing all outstanding events.  Added
locking to protect the ring index pointer.

This will call copy_from_user or scsi_map_user_pages, both of which
can sleep.  We need to operate in user context but by processing all
outstanding requests before returning from the write in a single 
thread, the user process is held in the write for a very long period 
of time and we can't process more than one at a time.  With this change
we can alter the userspace code to write from multiple threads.

---
 drivers/scsi/scsi_tgt_if.c |   31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

Index: b/drivers/scsi/scsi_tgt_if.c
===================================================================
--- a/drivers/scsi/scsi_tgt_if.c
+++ b/drivers/scsi/scsi_tgt_if.c
@@ -239,19 +239,26 @@ static ssize_t tgt_write(struct file *fi
 {
 	struct tgt_event *ev;
 	struct tgt_ring *ring = &rx_ring;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ring->tr_lock, flags);
+
+	ev = tgt_head_event(ring, ring->tr_idx);
+
+	if (!ev->hdr.status) {
+		spin_unlock_irqrestore(&ring->tr_lock, flags);
+		eprintk("no valid tgt_event found during tgt_write\n");
+		return count;
+	}
+
+	tgt_ring_idx_inc(ring);
+
+	spin_unlock_irqrestore(&ring->tr_lock, flags);
+
+	event_recv_msg(ev);
 
-	while (1) {
-		ev = tgt_head_event(ring, ring->tr_idx);
-		/* do we need this? */
-		flush_dcache_page(virt_to_page(ev));
-
-		if (!ev->hdr.status)
-			break;
-
-		tgt_ring_idx_inc(ring);
-		event_recv_msg(ev);
-		ev->hdr.status = 0;
-	};
+	ev->hdr.status = 0;
+	flush_dcache_page(virt_to_page(ev));
 
 	return count;
 }



More information about the stgt mailing list