Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tcp: add tcp_sock_set_cork

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>

authored by

Christoph Hellwig and committed by
David S. Miller
db10538a fe31a326

+43 -51
-14
drivers/block/drbd/drbd_int.h
··· 1570 1570 extern void _drbd_clear_done_ee(struct drbd_device *device, struct list_head *to_be_freed); 1571 1571 extern int drbd_connected(struct drbd_peer_device *); 1572 1572 1573 - static inline void drbd_tcp_cork(struct socket *sock) 1574 - { 1575 - int val = 1; 1576 - (void) kernel_setsockopt(sock, SOL_TCP, TCP_CORK, 1577 - (char*)&val, sizeof(val)); 1578 - } 1579 - 1580 - static inline void drbd_tcp_uncork(struct socket *sock) 1581 - { 1582 - int val = 0; 1583 - (void) kernel_setsockopt(sock, SOL_TCP, TCP_CORK, 1584 - (char*)&val, sizeof(val)); 1585 - } 1586 - 1587 1573 static inline void drbd_tcp_nodelay(struct socket *sock) 1588 1574 { 1589 1575 int val = 1;
+2 -2
drivers/block/drbd/drbd_receiver.c
··· 6162 6162 rcu_read_unlock(); 6163 6163 6164 6164 if (tcp_cork) 6165 - drbd_tcp_cork(connection->meta.socket); 6165 + tcp_sock_set_cork(connection->meta.socket->sk, true); 6166 6166 6167 6167 err = drbd_finish_peer_reqs(device); 6168 6168 kref_put(&device->kref, drbd_destroy_device); ··· 6175 6175 } 6176 6176 6177 6177 if (tcp_cork) 6178 - drbd_tcp_uncork(connection->meta.socket); 6178 + tcp_sock_set_cork(connection->meta.socket->sk, false); 6179 6179 6180 6180 return; 6181 6181 }
+3 -3
drivers/block/drbd/drbd_worker.c
··· 2098 2098 if (uncork) { 2099 2099 mutex_lock(&connection->data.mutex); 2100 2100 if (connection->data.socket) 2101 - drbd_tcp_uncork(connection->data.socket); 2101 + tcp_sock_set_cork(connection->data.socket->sk, false); 2102 2102 mutex_unlock(&connection->data.mutex); 2103 2103 } 2104 2104 ··· 2153 2153 mutex_lock(&connection->data.mutex); 2154 2154 if (connection->data.socket) { 2155 2155 if (cork) 2156 - drbd_tcp_cork(connection->data.socket); 2156 + tcp_sock_set_cork(connection->data.socket->sk, true); 2157 2157 else if (!uncork) 2158 - drbd_tcp_uncork(connection->data.socket); 2158 + tcp_sock_set_cork(connection->data.socket->sk, false); 2159 2159 } 2160 2160 mutex_unlock(&connection->data.mutex); 2161 2161 }
+2 -6
fs/cifs/transport.c
··· 325 325 size_t total_len = 0, sent, size; 326 326 struct socket *ssocket = server->ssocket; 327 327 struct msghdr smb_msg; 328 - int val = 1; 329 328 __be32 rfc1002_marker; 330 329 331 330 if (cifs_rdma_enabled(server)) { ··· 344 345 } 345 346 346 347 /* cork the socket */ 347 - kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK, 348 - (char *)&val, sizeof(val)); 348 + tcp_sock_set_cork(ssocket->sk, true); 349 349 350 350 for (j = 0; j < num_rqst; j++) 351 351 send_length += smb_rqst_len(server, &rqst[j]); ··· 433 435 } 434 436 435 437 /* uncork it */ 436 - val = 0; 437 - kernel_setsockopt(ssocket, SOL_TCP, TCP_CORK, 438 - (char *)&val, sizeof(val)); 438 + tcp_sock_set_cork(ssocket->sk, false); 439 439 440 440 if ((total_len > 0) && (total_len != send_length)) { 441 441 cifs_dbg(FYI, "partial send (wanted=%u sent=%zu): terminating session\n",
+2
include/linux/tcp.h
··· 497 497 int tcp_skb_shift(struct sk_buff *to, struct sk_buff *from, int pcount, 498 498 int shiftlen); 499 499 500 + void tcp_sock_set_cork(struct sock *sk, bool on); 501 + 500 502 #endif /* _LINUX_TCP_H */
+32 -19
net/ipv4/tcp.c
··· 2801 2801 } 2802 2802 } 2803 2803 2804 + /* When set indicates to always queue non-full frames. Later the user clears 2805 + * this option and we transmit any pending partial frames in the queue. This is 2806 + * meant to be used alongside sendfile() to get properly filled frames when the 2807 + * user (for example) must write out headers with a write() call first and then 2808 + * use sendfile to send out the data parts. 2809 + * 2810 + * TCP_CORK can be set together with TCP_NODELAY and it is stronger than 2811 + * TCP_NODELAY. 2812 + */ 2813 + static void __tcp_sock_set_cork(struct sock *sk, bool on) 2814 + { 2815 + struct tcp_sock *tp = tcp_sk(sk); 2816 + 2817 + if (on) { 2818 + tp->nonagle |= TCP_NAGLE_CORK; 2819 + } else { 2820 + tp->nonagle &= ~TCP_NAGLE_CORK; 2821 + if (tp->nonagle & TCP_NAGLE_OFF) 2822 + tp->nonagle |= TCP_NAGLE_PUSH; 2823 + tcp_push_pending_frames(sk); 2824 + } 2825 + } 2826 + 2827 + void tcp_sock_set_cork(struct sock *sk, bool on) 2828 + { 2829 + lock_sock(sk); 2830 + __tcp_sock_set_cork(sk, on); 2831 + release_sock(sk); 2832 + } 2833 + EXPORT_SYMBOL(tcp_sock_set_cork); 2834 + 2804 2835 /* 2805 2836 * Socket option code for TCP. 2806 2837 */ ··· 3010 2979 break; 3011 2980 3012 2981 case TCP_CORK: 3013 - /* When set indicates to always queue non-full frames. 3014 - * Later the user clears this option and we transmit 3015 - * any pending partial frames in the queue. This is 3016 - * meant to be used alongside sendfile() to get properly 3017 - * filled frames when the user (for example) must write 3018 - * out headers with a write() call first and then use 3019 - * sendfile to send out the data parts. 3020 - * 3021 - * TCP_CORK can be set together with TCP_NODELAY and it is 3022 - * stronger than TCP_NODELAY. 3023 - */ 3024 - if (val) { 3025 - tp->nonagle |= TCP_NAGLE_CORK; 3026 - } else { 3027 - tp->nonagle &= ~TCP_NAGLE_CORK; 3028 - if (tp->nonagle&TCP_NAGLE_OFF) 3029 - tp->nonagle |= TCP_NAGLE_PUSH; 3030 - tcp_push_pending_frames(sk); 3031 - } 2982 + __tcp_sock_set_cork(sk, val); 3032 2983 break; 3033 2984 3034 2985 case TCP_KEEPIDLE:
+2 -7
net/rds/tcp_send.c
··· 38 38 #include "rds.h" 39 39 #include "tcp.h" 40 40 41 - static void rds_tcp_cork(struct socket *sock, int val) 42 - { 43 - kernel_setsockopt(sock, SOL_TCP, TCP_CORK, (void *)&val, sizeof(val)); 44 - } 45 - 46 41 void rds_tcp_xmit_path_prepare(struct rds_conn_path *cp) 47 42 { 48 43 struct rds_tcp_connection *tc = cp->cp_transport_data; 49 44 50 - rds_tcp_cork(tc->t_sock, 1); 45 + tcp_sock_set_cork(tc->t_sock->sk, true); 51 46 } 52 47 53 48 void rds_tcp_xmit_path_complete(struct rds_conn_path *cp) 54 49 { 55 50 struct rds_tcp_connection *tc = cp->cp_transport_data; 56 51 57 - rds_tcp_cork(tc->t_sock, 0); 52 + tcp_sock_set_cork(tc->t_sock->sk, false); 58 53 } 59 54 60 55 /* the core send_sem serializes this with other xmit and shutdown */