diff mbox series

[v3,41/55] iscsi: Assume "sendpage" is okay in iscsi_tcp_segment_map()

Message ID 20230331160914.1608208-42-dhowells@redhat.com (mailing list archive)
State New
Headers show
Series splice, net: Replace sendpage with sendmsg(MSG_SPLICE_PAGES) | expand

Commit Message

David Howells March 31, 2023, 4:09 p.m. UTC
As iscsi is now using sendmsg() with MSG_SPLICE_PAGES rather than sendpage,
assume that sendpage_ok() will return true in iscsi_tcp_segment_map() and
leave it to TCP to copy the data if not.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: "Martin K. Petersen" <martin.petersen@oracle.com>
cc: "David S. Miller" <davem@davemloft.net>
cc: Eric Dumazet <edumazet@google.com>
cc: Jakub Kicinski <kuba@kernel.org>
cc: Paolo Abeni <pabeni@redhat.com>
cc: Jens Axboe <axboe@kernel.dk>
cc: Matthew Wilcox <willy@infradead.org>
cc: linux-scsi@vger.kernel.org
cc: target-devel@vger.kernel.org
cc: netdev@vger.kernel.org
---
 drivers/scsi/libiscsi_tcp.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

Comments

Fabio M. De Francesco April 24, 2023, 5:19 p.m. UTC | #1
On venerdì 31 marzo 2023 18:09:00 CEST David Howells wrote:
> As iscsi is now using sendmsg() with MSG_SPLICE_PAGES rather than sendpage,
> assume that sendpage_ok() will return true in iscsi_tcp_segment_map() and
> leave it to TCP to copy the data if not.
> 
> Signed-off-by: David Howells <dhowells@redhat.com>
> cc: "Martin K. Petersen" <martin.petersen@oracle.com>
> cc: "David S. Miller" <davem@davemloft.net>
> cc: Eric Dumazet <edumazet@google.com>
> cc: Jakub Kicinski <kuba@kernel.org>
> cc: Paolo Abeni <pabeni@redhat.com>
> cc: Jens Axboe <axboe@kernel.dk>
> cc: Matthew Wilcox <willy@infradead.org>
> cc: linux-scsi@vger.kernel.org
> cc: target-devel@vger.kernel.org
> cc: netdev@vger.kernel.org
> ---
>  drivers/scsi/libiscsi_tcp.c | 13 +++----------
>  1 file changed, 3 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
> index c182aa83f2c9..07ba0d864820 100644
> --- a/drivers/scsi/libiscsi_tcp.c
> +++ b/drivers/scsi/libiscsi_tcp.c
> @@ -128,18 +128,11 @@ static void iscsi_tcp_segment_map(struct iscsi_segment
> *segment, int recv) * coalescing neighboring slab objects into a single frag
> which
>  	 * triggers one of hardened usercopy checks.
>  	 */
> -	if (!recv && sendpage_ok(sg_page(sg)))
> +	if (!recv)
>  		return;
> 
> -	if (recv) {
> -		segment->atomic_mapped = true;
> -		segment->sg_mapped = kmap_atomic(sg_page(sg));
> -	} else {
> -		segment->atomic_mapped = false;
> -		/* the xmit path can sleep with the page mapped so use 
kmap */
> -		segment->sg_mapped = kmap(sg_page(sg));
> -	}
> -
> +	segment->atomic_mapped = true;
> +	segment->sg_mapped = kmap_atomic(sg_page(sg));

As you probably know, kmap_atomic() is deprecated.

I must admit that I'm not an expert of this code, however, it looks like the 
mapping has no need to rely on the side effects of kmap_atomic() (i.e., 
pagefault_disable() and preempt_disable() - but I'm not entirely sure about 
the possibility that preemption should be explicitly disabled along with the 
replacement with kmap_local_page()). 

Last year I've been working on several conversions from kmap{,_atomic}() to 
kmap_local_page(), however I'm still not sure to understand what's happening 
here...

Am I missing any important details? Can you please explain why we still need 
that kmap_atomic() instead of kmap_local_page()? 

Thanks in advance,

Fabio

>  	segment->data = segment->sg_mapped + sg->offset + segment-
>sg_offset;
>  }
David Howells April 25, 2023, 8:30 a.m. UTC | #2
Fabio M. De Francesco <fmdefrancesco@gmail.com> wrote:

> > -	if (recv) {
> > -		segment->atomic_mapped = true;
> > -		segment->sg_mapped = kmap_atomic(sg_page(sg));
> > -	} else {
> > -		segment->atomic_mapped = false;
> > -		/* the xmit path can sleep with the page mapped so use 
> kmap */
> > -		segment->sg_mapped = kmap(sg_page(sg));
> > -	}
> > -
> > +	segment->atomic_mapped = true;
> > +	segment->sg_mapped = kmap_atomic(sg_page(sg));
> 
> As you probably know, kmap_atomic() is deprecated.
> 
> I must admit that I'm not an expert of this code, however, it looks like the 
> mapping has no need to rely on the side effects of kmap_atomic() (i.e., 
> pagefault_disable() and preempt_disable() - but I'm not entirely sure about 
> the possibility that preemption should be explicitly disabled along with the 
> replacement with kmap_local_page()). 
> 
> Last year I've been working on several conversions from kmap{,_atomic}() to 
> kmap_local_page(), however I'm still not sure to understand what's happening 
> here...
> 
> Am I missing any important details? Can you please explain why we still need 
> that kmap_atomic() instead of kmap_local_page()? 

Actually, it might be worth dropping segment->sg_mapped and segment->data and
only doing the kmap_local when necessary.

And this:

			struct msghdr msg = { .msg_flags = flags };
			struct kvec iov = {
				.iov_base = segment->data + offset,
				.iov_len = copy
			};

			r = kernel_sendmsg(sk, &msg, &iov, 1, copy);

should really be using struct bvec, not struct kvec - then the mapping isn't
necessary.  It looks like this might be the only place the mapping is used,
but I'm not 100% certain.

David
Fabio M. De Francesco April 25, 2023, 1:13 p.m. UTC | #3
On martedì 25 aprile 2023 10:30:30 CEST David Howells wrote:
> Fabio M. De Francesco <fmdefrancesco@gmail.com> wrote:
> > > -	if (recv) {
> > > -		segment->atomic_mapped = true;
> > > -		segment->sg_mapped = kmap_atomic(sg_page(sg));
> > > -	} else {
> > > -		segment->atomic_mapped = false;
> > > -		/* the xmit path can sleep with the page mapped so use
> > 
> > kmap */
> > 
> > > -		segment->sg_mapped = kmap(sg_page(sg));
> > > -	}
> > > -
> > > +	segment->atomic_mapped = true;
> > > +	segment->sg_mapped = kmap_atomic(sg_page(sg));
> > 
> > As you probably know, kmap_atomic() is deprecated.
> > 
> > I must admit that I'm not an expert of this code, however, it looks like 
the
> > mapping has no need to rely on the side effects of kmap_atomic() (i.e.,
> > pagefault_disable() and preempt_disable() - but I'm not entirely sure 
about
> > the possibility that preemption should be explicitly disabled along with 
the
> > replacement with kmap_local_page()).
> > 
> > Last year I've been working on several conversions from kmap{,_atomic}() 
to
> > kmap_local_page(), however I'm still not sure to understand what's 
happening
> > here...
> > 
> > Am I missing any important details? Can you please explain why we still 
need
> > that kmap_atomic() instead of kmap_local_page()?
> 
> Actually, it might be worth dropping segment->sg_mapped and segment->data 
and
> only doing the kmap_local when necessary.
> 
> And this:
> 
> 			struct msghdr msg = { .msg_flags = flags };
> 			struct kvec iov = {
> 				.iov_base = segment->data + offset,
> 				.iov_len = copy
> 			};
> 
> 			r = kernel_sendmsg(sk, &msg, &iov, 1, copy);
> 
> should really be using struct bvec, not struct kvec - then the mapping isn't
> necessary.

FWIW, struct bvec looks better suited (despite I have very little knowledge of 
this code).

I assume that you noticed that we also have the unmapping counterpart 
(iscsi_tcp_segment_unmap()) which should also be addressed accordingly.

> It looks like this might be the only place the mapping is used,
> but I'm not 100% certain.

It seems that kmap_atomic() (as well as kmap(), which you deleted) is only 
called by iscsi_tcp_segment_map(), which in turn is called only by  
iscsi_tcp_segment_done(). I can't see any other places where the mapping is 
used.

I hope that this dialogue may help you somehow to choose the best suited way 
to get rid of that deprecated kmap_atomic().

Thanks for taking time to address questions from newcomers :-) 

Fabio

> 
> David
diff mbox series

Patch

diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index c182aa83f2c9..07ba0d864820 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -128,18 +128,11 @@  static void iscsi_tcp_segment_map(struct iscsi_segment *segment, int recv)
 	 * coalescing neighboring slab objects into a single frag which
 	 * triggers one of hardened usercopy checks.
 	 */
-	if (!recv && sendpage_ok(sg_page(sg)))
+	if (!recv)
 		return;
 
-	if (recv) {
-		segment->atomic_mapped = true;
-		segment->sg_mapped = kmap_atomic(sg_page(sg));
-	} else {
-		segment->atomic_mapped = false;
-		/* the xmit path can sleep with the page mapped so use kmap */
-		segment->sg_mapped = kmap(sg_page(sg));
-	}
-
+	segment->atomic_mapped = true;
+	segment->sg_mapped = kmap_atomic(sg_page(sg));
 	segment->data = segment->sg_mapped + sg->offset + segment->sg_offset;
 }