diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-08-13 16:54:57 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-09-30 15:35:14 -0400 |
commit | 6c7a64e5a44dbc6d073b83a56a48d0a4099f1dd2 (patch) | |
tree | 1132aea419985a086e4b7760b31345905f6adb7b /net/sunrpc/xprtsock.c | |
parent | e1806c7bfb803408df4dc53dfe502ffab0f46a67 (diff) |
SUNRPC: Add socket transmit queue offset tracking
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'net/sunrpc/xprtsock.c')
-rw-r--r-- | net/sunrpc/xprtsock.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index ec1e3f93e707..629cc45e1e6c 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -461,7 +461,7 @@ static int xs_nospace(struct rpc_task *task) | |||
461 | int ret = -EAGAIN; | 461 | int ret = -EAGAIN; |
462 | 462 | ||
463 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", | 463 | dprintk("RPC: %5u xmit incomplete (%u left of %u)\n", |
464 | task->tk_pid, req->rq_slen - req->rq_bytes_sent, | 464 | task->tk_pid, req->rq_slen - transport->xmit.offset, |
465 | req->rq_slen); | 465 | req->rq_slen); |
466 | 466 | ||
467 | /* Protect against races with write_space */ | 467 | /* Protect against races with write_space */ |
@@ -528,19 +528,22 @@ static int xs_local_send_request(struct rpc_task *task) | |||
528 | req->rq_svec->iov_base, req->rq_svec->iov_len); | 528 | req->rq_svec->iov_base, req->rq_svec->iov_len); |
529 | 529 | ||
530 | req->rq_xtime = ktime_get(); | 530 | req->rq_xtime = ktime_get(); |
531 | status = xs_sendpages(transport->sock, NULL, 0, xdr, req->rq_bytes_sent, | 531 | status = xs_sendpages(transport->sock, NULL, 0, xdr, |
532 | transport->xmit.offset, | ||
532 | true, &sent); | 533 | true, &sent); |
533 | dprintk("RPC: %s(%u) = %d\n", | 534 | dprintk("RPC: %s(%u) = %d\n", |
534 | __func__, xdr->len - req->rq_bytes_sent, status); | 535 | __func__, xdr->len - transport->xmit.offset, status); |
535 | 536 | ||
536 | if (status == -EAGAIN && sock_writeable(transport->inet)) | 537 | if (status == -EAGAIN && sock_writeable(transport->inet)) |
537 | status = -ENOBUFS; | 538 | status = -ENOBUFS; |
538 | 539 | ||
539 | if (likely(sent > 0) || status == 0) { | 540 | if (likely(sent > 0) || status == 0) { |
540 | req->rq_bytes_sent += sent; | 541 | transport->xmit.offset += sent; |
541 | req->rq_xmit_bytes_sent += sent; | 542 | req->rq_bytes_sent = transport->xmit.offset; |
542 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { | 543 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { |
544 | req->rq_xmit_bytes_sent += transport->xmit.offset; | ||
543 | req->rq_bytes_sent = 0; | 545 | req->rq_bytes_sent = 0; |
546 | transport->xmit.offset = 0; | ||
544 | return 0; | 547 | return 0; |
545 | } | 548 | } |
546 | status = -EAGAIN; | 549 | status = -EAGAIN; |
@@ -592,10 +595,10 @@ static int xs_udp_send_request(struct rpc_task *task) | |||
592 | return -ENOTCONN; | 595 | return -ENOTCONN; |
593 | req->rq_xtime = ktime_get(); | 596 | req->rq_xtime = ktime_get(); |
594 | status = xs_sendpages(transport->sock, xs_addr(xprt), xprt->addrlen, | 597 | status = xs_sendpages(transport->sock, xs_addr(xprt), xprt->addrlen, |
595 | xdr, req->rq_bytes_sent, true, &sent); | 598 | xdr, 0, true, &sent); |
596 | 599 | ||
597 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", | 600 | dprintk("RPC: xs_udp_send_request(%u) = %d\n", |
598 | xdr->len - req->rq_bytes_sent, status); | 601 | xdr->len, status); |
599 | 602 | ||
600 | /* firewall is blocking us, don't return -EAGAIN or we end up looping */ | 603 | /* firewall is blocking us, don't return -EAGAIN or we end up looping */ |
601 | if (status == -EPERM) | 604 | if (status == -EPERM) |
@@ -684,17 +687,20 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
684 | while (1) { | 687 | while (1) { |
685 | sent = 0; | 688 | sent = 0; |
686 | status = xs_sendpages(transport->sock, NULL, 0, xdr, | 689 | status = xs_sendpages(transport->sock, NULL, 0, xdr, |
687 | req->rq_bytes_sent, zerocopy, &sent); | 690 | transport->xmit.offset, |
691 | zerocopy, &sent); | ||
688 | 692 | ||
689 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", | 693 | dprintk("RPC: xs_tcp_send_request(%u) = %d\n", |
690 | xdr->len - req->rq_bytes_sent, status); | 694 | xdr->len - transport->xmit.offset, status); |
691 | 695 | ||
692 | /* If we've sent the entire packet, immediately | 696 | /* If we've sent the entire packet, immediately |
693 | * reset the count of bytes sent. */ | 697 | * reset the count of bytes sent. */ |
694 | req->rq_bytes_sent += sent; | 698 | transport->xmit.offset += sent; |
695 | req->rq_xmit_bytes_sent += sent; | 699 | req->rq_bytes_sent = transport->xmit.offset; |
696 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { | 700 | if (likely(req->rq_bytes_sent >= req->rq_slen)) { |
701 | req->rq_xmit_bytes_sent += transport->xmit.offset; | ||
697 | req->rq_bytes_sent = 0; | 702 | req->rq_bytes_sent = 0; |
703 | transport->xmit.offset = 0; | ||
698 | return 0; | 704 | return 0; |
699 | } | 705 | } |
700 | 706 | ||
@@ -760,18 +766,13 @@ static int xs_tcp_send_request(struct rpc_task *task) | |||
760 | */ | 766 | */ |
761 | static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) | 767 | static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) |
762 | { | 768 | { |
763 | struct rpc_rqst *req; | 769 | struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt); |
764 | 770 | ||
765 | if (task != xprt->snd_task) | 771 | if (task != xprt->snd_task) |
766 | return; | 772 | return; |
767 | if (task == NULL) | 773 | if (task == NULL) |
768 | goto out_release; | 774 | goto out_release; |
769 | req = task->tk_rqstp; | 775 | if (transport->xmit.offset == 0 || !xprt_connected(xprt)) |
770 | if (req == NULL) | ||
771 | goto out_release; | ||
772 | if (req->rq_bytes_sent == 0) | ||
773 | goto out_release; | ||
774 | if (req->rq_bytes_sent == req->rq_snd_buf.len) | ||
775 | goto out_release; | 776 | goto out_release; |
776 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); | 777 | set_bit(XPRT_CLOSE_WAIT, &xprt->state); |
777 | out_release: | 778 | out_release: |
@@ -2021,6 +2022,8 @@ static int xs_local_finish_connecting(struct rpc_xprt *xprt, | |||
2021 | write_unlock_bh(&sk->sk_callback_lock); | 2022 | write_unlock_bh(&sk->sk_callback_lock); |
2022 | } | 2023 | } |
2023 | 2024 | ||
2025 | transport->xmit.offset = 0; | ||
2026 | |||
2024 | /* Tell the socket layer to start connecting... */ | 2027 | /* Tell the socket layer to start connecting... */ |
2025 | xprt->stat.connect_count++; | 2028 | xprt->stat.connect_count++; |
2026 | xprt->stat.connect_start = jiffies; | 2029 | xprt->stat.connect_start = jiffies; |
@@ -2384,6 +2387,7 @@ static int xs_tcp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | |||
2384 | transport->recv.len = 0; | 2387 | transport->recv.len = 0; |
2385 | transport->recv.copied = 0; | 2388 | transport->recv.copied = 0; |
2386 | transport->recv.flags = TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; | 2389 | transport->recv.flags = TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID; |
2390 | transport->xmit.offset = 0; | ||
2387 | 2391 | ||
2388 | /* Tell the socket layer to start connecting... */ | 2392 | /* Tell the socket layer to start connecting... */ |
2389 | xprt->stat.connect_count++; | 2393 | xprt->stat.connect_count++; |