SUNRPC: Restructure svc_udp_recvfrom()
authorChuck Lever <chuck.lever@oracle.com>
Wed, 20 May 2020 21:30:24 +0000 (17:30 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Wed, 20 May 2020 21:30:24 +0000 (17:30 -0400)
Clean up. At this point, we are not ready yet to support bio_vecs in
the UDP transport implementation. However, we can clean up
svc_udp_recvfrom() to match the tracing and straight-lining recently
changes made in svc_tcp_recvfrom().

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
include/trace/events/sunrpc.h
net/sunrpc/svcsock.c

index 81659876b4afaf7270f3332a9dd17458d6935821..08c7d618ceb49c16fb9c8e49a421c586dca34808 100644 (file)
@@ -1501,6 +1501,8 @@ DECLARE_EVENT_CLASS(svcsock_class,
                        TP_ARGS(xprt, result))
 
 DEFINE_SVCSOCK_EVENT(udp_send);
+DEFINE_SVCSOCK_EVENT(udp_recv);
+DEFINE_SVCSOCK_EVENT(udp_recv_err);
 DEFINE_SVCSOCK_EVENT(tcp_send);
 DEFINE_SVCSOCK_EVENT(tcp_recv);
 DEFINE_SVCSOCK_EVENT(tcp_recv_eagain);
index 3e25511b800e8fde8b806fe9e8c3400b5fb1b75b..97d2b6f8c7918f157a4684c9221b8fd89c436e82 100644 (file)
@@ -425,8 +425,15 @@ static int svc_udp_get_dest_address(struct svc_rqst *rqstp,
        return 0;
 }
 
-/*
- * Receive a datagram from a UDP socket.
+/**
+ * svc_udp_recvfrom - Receive a datagram from a UDP socket.
+ * @rqstp: request structure into which to receive an RPC Call
+ *
+ * Called in a loop when XPT_DATA has been set.
+ *
+ * Returns:
+ *   On success, the number of bytes in a received RPC Call, or
+ *   %0 if a complete RPC Call message was not ready to return
  */
 static int svc_udp_recvfrom(struct svc_rqst *rqstp)
 {
@@ -460,20 +467,14 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
            svc_sock_setbufsize(svsk, serv->sv_nrthreads + 3);
 
        clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
-       skb = NULL;
        err = kernel_recvmsg(svsk->sk_sock, &msg, NULL,
                             0, 0, MSG_PEEK | MSG_DONTWAIT);
-       if (err >= 0)
-               skb = skb_recv_udp(svsk->sk_sk, 0, 1, &err);
-
-       if (skb == NULL) {
-               if (err != -EAGAIN) {
-                       /* possibly an icmp error */
-                       dprintk("svc: recvfrom returned error %d\n", -err);
-                       set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
-               }
-               return 0;
-       }
+       if (err < 0)
+               goto out_recv_err;
+       skb = skb_recv_udp(svsk->sk_sk, 0, 1, &err);
+       if (!skb)
+               goto out_recv_err;
+
        len = svc_addr_len(svc_addr(rqstp));
        rqstp->rq_addrlen = len;
        if (skb->tstamp == 0) {
@@ -484,26 +485,21 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
        sock_write_timestamp(svsk->sk_sk, skb->tstamp);
        set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* there may be more data... */
 
-       len  = skb->len;
+       len = skb->len;
        rqstp->rq_arg.len = len;
+       trace_svcsock_udp_recv(&svsk->sk_xprt, len);
 
        rqstp->rq_prot = IPPROTO_UDP;
 
-       if (!svc_udp_get_dest_address(rqstp, cmh)) {
-               net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n",
-                                    cmh->cmsg_level, cmh->cmsg_type);
-               goto out_free;
-       }
+       if (!svc_udp_get_dest_address(rqstp, cmh))
+               goto out_cmsg_err;
        rqstp->rq_daddrlen = svc_addr_len(svc_daddr(rqstp));
 
        if (skb_is_nonlinear(skb)) {
                /* we have to copy */
                local_bh_disable();
-               if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb)) {
-                       local_bh_enable();
-                       /* checksum error */
-                       goto out_free;
-               }
+               if (csum_partial_copy_to_xdr(&rqstp->rq_arg, skb))
+                       goto out_bh_enable;
                local_bh_enable();
                consume_skb(skb);
        } else {
@@ -531,6 +527,20 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
                serv->sv_stats->netudpcnt++;
 
        return len;
+
+out_recv_err:
+       if (err != -EAGAIN) {
+               /* possibly an icmp error */
+               set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags);
+       }
+       trace_svcsock_udp_recv_err(&svsk->sk_xprt, err);
+       return 0;
+out_cmsg_err:
+       net_warn_ratelimited("svc: received unknown control message %d/%d; dropping RPC reply datagram\n",
+                            cmh->cmsg_level, cmh->cmsg_type);
+       goto out_free;
+out_bh_enable:
+       local_bh_enable();
 out_free:
        kfree_skb(skb);
        return 0;