[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