Commit 70c7c88a1a65ca683eb7f3fe3ce79c72f29d845e

Authored by Mike Christie
Committed by James Bottomley
1 parent e8b12f0fb8

[SCSI] libiscsi_tcp: use kmap in xmit path

The xmit path can sleep with a page kmapped in the network
xmit code while it waits for space to open up, so we have to use
kmap instead of kmap atomic in that path.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>

Showing 2 changed files with 14 additions and 2 deletions Side-by-side Diff

drivers/scsi/libiscsi_tcp.c
... ... @@ -132,14 +132,25 @@
132 132 if (page_count(sg_page(sg)) >= 1 && !recv)
133 133 return;
134 134  
135   - segment->sg_mapped = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
  135 + if (recv) {
  136 + segment->atomic_mapped = true;
  137 + segment->sg_mapped = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
  138 + } else {
  139 + segment->atomic_mapped = false;
  140 + /* the xmit path can sleep with the page mapped so use kmap */
  141 + segment->sg_mapped = kmap(sg_page(sg));
  142 + }
  143 +
136 144 segment->data = segment->sg_mapped + sg->offset + segment->sg_offset;
137 145 }
138 146  
139 147 void iscsi_tcp_segment_unmap(struct iscsi_segment *segment)
140 148 {
141 149 if (segment->sg_mapped) {
142   - kunmap_atomic(segment->sg_mapped, KM_SOFTIRQ0);
  150 + if (segment->atomic_mapped)
  151 + kunmap_atomic(segment->sg_mapped, KM_SOFTIRQ0);
  152 + else
  153 + kunmap(sg_page(segment->sg));
143 154 segment->sg_mapped = NULL;
144 155 segment->data = NULL;
145 156 }
include/scsi/libiscsi_tcp.h
... ... @@ -47,6 +47,7 @@
47 47 struct scatterlist *sg;
48 48 void *sg_mapped;
49 49 unsigned int sg_offset;
  50 + bool atomic_mapped;
50 51  
51 52 iscsi_segment_done_fn_t *done;
52 53 };