drbd: Use sendmsg(MSG_SPLICE_PAGES) rather than sendpage()
authorDavid Howells <dhowells@redhat.com>
Fri, 23 Jun 2023 22:55:07 +0000 (23:55 +0100)
committerJakub Kicinski <kuba@kernel.org>
Sat, 24 Jun 2023 22:50:13 +0000 (15:50 -0700)
Use sendmsg() conditionally with MSG_SPLICE_PAGES in _drbd_send_page()
rather than calling sendpage() or _drbd_no_send_page().

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Philipp Reisner <philipp.reisner@linbit.com>
cc: Lars Ellenberg <lars.ellenberg@linbit.com>
cc: "Christoph Böhmwalder" <christoph.boehmwalder@linbit.com>
cc: Jens Axboe <axboe@kernel.dk>
cc: drbd-dev@lists.linbit.com
Link: https://lore.kernel.org/r/20230623225513.2732256-11-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/block/drbd/drbd_main.c

index 83987e7..ea82d67 100644 (file)
@@ -1540,6 +1540,8 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
                    int offset, size_t size, unsigned msg_flags)
 {
        struct socket *socket = peer_device->connection->data.socket;
+       struct msghdr msg = { .msg_flags = msg_flags, };
+       struct bio_vec bvec;
        int len = size;
        int err = -EIO;
 
@@ -1549,15 +1551,17 @@ static int _drbd_send_page(struct drbd_peer_device *peer_device, struct page *pa
         * put_page(); and would cause either a VM_BUG directly, or
         * __page_cache_release a page that would actually still be referenced
         * by someone, leading to some obscure delayed Oops somewhere else. */
-       if (drbd_disable_sendpage || !sendpage_ok(page))
-               return _drbd_no_send_page(peer_device, page, offset, size, msg_flags);
+       if (!drbd_disable_sendpage && sendpage_ok(page))
+               msg.msg_flags |= MSG_NOSIGNAL | MSG_SPLICE_PAGES;
 
-       msg_flags |= MSG_NOSIGNAL;
        drbd_update_congested(peer_device->connection);
        do {
                int sent;
 
-               sent = socket->ops->sendpage(socket, page, offset, len, msg_flags);
+               bvec_set_page(&bvec, page, offset, len);
+               iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, len);
+
+               sent = sock_sendmsg(socket, &msg);
                if (sent <= 0) {
                        if (sent == -EAGAIN) {
                                if (we_should_drop_the_connection(peer_device->connection, socket))