]> git.baikalelectronics.ru Git - kernel.git/commitdiff
tcp: add tcp_sock_set_cork
authorChristoph Hellwig <hch@lst.de>
Thu, 28 May 2020 05:12:18 +0000 (07:12 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 May 2020 18:11:45 +0000 (11:11 -0700)
Add a helper to directly set the TCP_CORK sockopt from kernel space
without going through a fake uaccess.  Cleanup the callers to avoid
pointless wrappers now that this is a simple function call.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
fs/cifs/transport.c
include/linux/tcp.h
net/ipv4/tcp.c
net/rds/tcp_send.c

index aae99a2d7bd40fa43afb3e0d59c1d3ca09b14fd2..3550adc93c68b0243f5009d72204491949af5b11 100644 (file)
@@ -1570,20 +1570,6 @@ extern void drbd_set_recv_tcq(struct drbd_device *device, int tcq_enabled);
 extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed);
 extern int drbd_connected(struct drbd_peer_device *);
 
-static inline void drbd_tcp_cork(struct socket *sock)
-{
-       int val = 1;
-       (void) kernel_setsockopt(sock, SOL_TCP, TCP_CORK,
-                       (char*)&val, sizeof(val));
-}
-
-static inline void drbd_tcp_uncork(struct socket *sock)
-{
-       int val = 0;
-       (void) kernel_setsockopt(sock, SOL_TCP, TCP_CORK,
-                       (char*)&val, sizeof(val));
-}
-
 static inline void drbd_tcp_nodelay(struct socket *sock)
 {
        int val = 1;
index c15e7083b13a607deae088cde443df36eec0f088..55ea907ad33cb78e21502c9e21625c681df7028f 100644 (file)
@@ -6162,7 +6162,7 @@ void drbd_send_acks_wf(struct work_struct *ws)
        rcu_read_unlock();
 
        if (tcp_cork)
-               drbd_tcp_cork(connection->meta.socket);
+               tcp_sock_set_cork(connection->meta.socket->sk, true);
 
        err = drbd_finish_peer_reqs(device);
        kref_put(&device->kref, drbd_destroy_device);
@@ -6175,7 +6175,7 @@ void drbd_send_acks_wf(struct work_struct *ws)
        }
 
        if (tcp_cork)
-               drbd_tcp_uncork(connection->meta.socket);
+               tcp_sock_set_cork(connection->meta.socket->sk, false);
 
        return;
 }
index 0dc019da1f8d07f36e06d55ee1dadc98ccdf1245..2b89c9f2ca70750381b3ea519e13bab4e43f8200 100644 (file)
@@ -2098,7 +2098,7 @@ static void wait_for_work(struct drbd_connection *connection, struct list_head *
        if (uncork) {
                mutex_lock(&connection->data.mutex);
                if (connection->data.socket)
-                       drbd_tcp_uncork(connection->data.socket);
+                       tcp_sock_set_cork(connection->data.socket->sk, false);
                mutex_unlock(&connection->data.mutex);
        }
 
@@ -2153,9 +2153,9 @@ static void wait_for_work(struct drbd_connection *connection, struct list_head *
        mutex_lock(&connection->data.mutex);
        if (connection->data.socket) {
                if (cork)
-                       drbd_tcp_cork(connection->data.socket);
+                       tcp_sock_set_cork(connection->data.socket->sk, true);
                else if (!uncork)
-                       drbd_tcp_uncork(connection->data.socket);
+                       tcp_sock_set_cork(connection->data.socket->sk, false);
        }
        mutex_unlock(&connection->data.mutex);
 }
index c97570eb2c180add90730953c4eadd2e1c46371a..99760063e0006d5ca561fd68728ceed430068856 100644 (file)
@@ -325,7 +325,6 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
        size_t total_len = 0, sent, size;
        struct socket *ssocket = server->ssocket;
        struct msghdr smb_msg;
-       int val = 1;
        __be32 rfc1002_marker;
 
        if (cifs_rdma_enabled(server)) {
@@ -345,8 +344,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
        }
 
        /* cork the socket */
-       kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
-                               (char *)&val, sizeof(val));
+       tcp_sock_set_cork(ssocket->sk, true);
 
        for (j = 0; j < num_rqst; j++)
                send_length += smb_rqst_len(server, &rqst[j]);
@@ -435,9 +433,7 @@ unmask:
        }
 
        /* uncork it */
-       val = 0;
-       kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK,
-                               (char *)&val, sizeof(val));
+       tcp_sock_set_cork(ssocket->sk, false);
 
        if ((total_len > 0) && (total_len != send_length)) {
                cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
index bf44e85d709dcdb7e1b67816261fabcf0f4b5ea6..889eeb2256c2d5db53b56e8592c028f10fa72b6c 100644 (file)
@@ -497,4 +497,6 @@ static inline u16 tcp_mss_clamp(const struct tcp_sock *tp, u16 mss)
 int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount,
                  int shiftlen);
 
+void tcp_sock_set_cork(struct sock *sk, bool on);
+
 #endif /* _LINUX_TCP_H */
index 970064996377316bb1095641624a7aef57fa5813..e6cf702e16d66d8fe6e3898ef2ca3ff9a8072a8f 100644 (file)
@@ -2801,6 +2801,37 @@ static void tcp_enable_tx_delay(void)
        }
 }
 
+/* When set indicates to always queue non-full frames.  Later the user clears
+ * this option and we transmit any pending partial frames in the queue.  This is
+ * meant to be used alongside sendfile() to get properly filled frames when the
+ * user (for example) must write out headers with a write() call first and then
+ * use sendfile to send out the data parts.
+ *
+ * TCP_CORK can be set together with TCP_NODELAY and it is stronger than
+ * TCP_NODELAY.
+ */
+static void __tcp_sock_set_cork(struct sock *sk, bool on)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+
+       if (on) {
+               tp->nonagle |= TCP_NAGLE_CORK;
+       } else {
+               tp->nonagle &= ~TCP_NAGLE_CORK;
+               if (tp->nonagle & TCP_NAGLE_OFF)
+                       tp->nonagle |= TCP_NAGLE_PUSH;
+               tcp_push_pending_frames(sk);
+       }
+}
+
+void tcp_sock_set_cork(struct sock *sk, bool on)
+{
+       lock_sock(sk);
+       __tcp_sock_set_cork(sk, on);
+       release_sock(sk);
+}
+EXPORT_SYMBOL(tcp_sock_set_cork);
+
 /*
  *     Socket option code for TCP.
  */
@@ -2979,25 +3010,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                break;
 
        case TCP_CORK:
-               /* When set indicates to always queue non-full frames.
-                * Later the user clears this option and we transmit
-                * any pending partial frames in the queue.  This is
-                * meant to be used alongside sendfile() to get properly
-                * filled frames when the user (for example) must write
-                * out headers with a write() call first and then use
-                * sendfile to send out the data parts.
-                *
-                * TCP_CORK can be set together with TCP_NODELAY and it is
-                * stronger than TCP_NODELAY.
-                */
-               if (val) {
-                       tp->nonagle |= TCP_NAGLE_CORK;
-               } else {
-                       tp->nonagle &= ~TCP_NAGLE_CORK;
-                       if (tp->nonagle&TCP_NAGLE_OFF)
-                               tp->nonagle |= TCP_NAGLE_PUSH;
-                       tcp_push_pending_frames(sk);
-               }
+               __tcp_sock_set_cork(sk, val);
                break;
 
        case TCP_KEEPIDLE:
index 78a2554a4497928e08c28874711ef15628f5d1fa..8c4d1d6e9249da9ea67b384ae0db196f829d2087 100644 (file)
 #include "rds.h"
 #include "tcp.h"
 
-static void rds_tcp_cork(struct socket *sock, int val)
-{
-       kernel_setsockopt(sock, SOL_TCP, TCP_CORK, (void *)&val, sizeof(val));
-}
-
 void rds_tcp_xmit_path_prepare(struct rds_conn_path *cp)
 {
        struct rds_tcp_connection *tc = cp->cp_transport_data;
 
-       rds_tcp_cork(tc->t_sock, 1);
+       tcp_sock_set_cork(tc->t_sock->sk, true);
 }
 
 void rds_tcp_xmit_path_complete(struct rds_conn_path *cp)
 {
        struct rds_tcp_connection *tc = cp->cp_transport_data;
 
-       rds_tcp_cork(tc->t_sock, 0);
+       tcp_sock_set_cork(tc->t_sock->sk, false);
 }
 
 /* the core send_sem serializes this with other xmit and shutdown */