Skip to content

Commit

Permalink
Merge branch 'remove-most-callers-of-kernel_setsockopt-v3'
Browse files Browse the repository at this point in the history
Christoph Hellwig says:

====================
remove most callers of kernel_setsockopt v3

this series removes most callers of the kernel_setsockopt functions, and
instead switches their users to small functions that implement setting a
sockopt directly using a normal kernel function call with type safety and
all the other benefits of not having a function call.

In some cases these functions seem pretty heavy handed as they do
a lock_sock even for just setting a single variable, but this mirrors
the real setsockopt implementation unlike a few drivers that just set
set the fields directly.

Changes since v2:
 - drop the separately merged kernel_getopt_removal
 - drop the sctp patches, as there is conflicting cleanup going on
 - add an additional ACK for the rxrpc changes

Changes since v1:
 - use ->getname for sctp sockets in dlm
 - add a new ->bind_add struct proto method for dlm/sctp
 - switch the ipv6 and remaining sctp helpers to inline function so that
   the ipv6 and sctp modules are not pulled in by any module that could
   potentially use ipv6 or sctp connections
 - remove arguments to various sock_* helpers that are always used with
   the same constant arguments
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed May 28, 2020
2 parents 1eba111 + 095ae61 commit 1e372db
Show file tree
Hide file tree
Showing 40 changed files with 609 additions and 639 deletions.
13 changes: 11 additions & 2 deletions Documentation/networking/rxrpc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ AF_RXRPC sockets support a few socket options at the SOL_RXRPC level:
Encrypted checksum plus packet padded and first eight bytes of packet
encrypted - which includes the actual packet length.

(c) RXRPC_SECURITY_ENCRYPTED
(c) RXRPC_SECURITY_ENCRYPT

Encrypted checksum plus entire packet padded and encrypted, including
actual packet length.
Expand Down Expand Up @@ -578,7 +578,7 @@ A client would issue an operation by:
This issues a request_key() to get the key representing the security
context. The minimum security level can be set::

unsigned int sec = RXRPC_SECURITY_ENCRYPTED;
unsigned int sec = RXRPC_SECURITY_ENCRYPT;
setsockopt(client, SOL_RXRPC, RXRPC_MIN_SECURITY_LEVEL,
&sec, sizeof(sec));

Expand Down Expand Up @@ -1090,6 +1090,15 @@ The kernel interface functions are as follows:
jiffies). In the event of the timeout occurring, the call will be
aborted and -ETIME or -ETIMEDOUT will be returned.

(#) Apply the RXRPC_MIN_SECURITY_LEVEL sockopt to a socket from within in the
kernel::

int rxrpc_sock_set_min_security_level(struct sock *sk,
unsigned int val);

This specifies the minimum security level required for calls on this
socket.


Configurable Parameters
=======================
Expand Down
28 changes: 0 additions & 28 deletions drivers/block/drbd/drbd_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -1570,34 +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;
(void) kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY,
(char*)&val, sizeof(val));
}

static inline void drbd_tcp_quickack(struct socket *sock)
{
int val = 2;
(void) kernel_setsockopt(sock, SOL_TCP, TCP_QUICKACK,
(char*)&val, sizeof(val));
}

/* sets the number of 512 byte sectors of our virtual device */
void drbd_set_my_capacity(struct drbd_device *device, sector_t size);

Expand Down
2 changes: 1 addition & 1 deletion drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ static int __send_command(struct drbd_connection *connection, int vnr,
/* DRBD protocol "pings" are latency critical.
* This is supposed to trigger tcp_push_pending_frames() */
if (!err && (cmd == P_PING || cmd == P_PING_ACK))
drbd_tcp_nodelay(sock->socket);
tcp_sock_set_nodelay(sock->socket->sk);

return err;
}
Expand Down
13 changes: 6 additions & 7 deletions drivers/block/drbd/drbd_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,8 +1051,8 @@ static int conn_connect(struct drbd_connection *connection)

/* we don't want delays.
* we use TCP_CORK where appropriate, though */
drbd_tcp_nodelay(sock.socket);
drbd_tcp_nodelay(msock.socket);
tcp_sock_set_nodelay(sock.socket->sk);
tcp_sock_set_nodelay(msock.socket->sk);

connection->data.socket = sock.socket;
connection->meta.socket = msock.socket;
Expand Down Expand Up @@ -1223,7 +1223,7 @@ static int drbd_recv_header_maybe_unplug(struct drbd_connection *connection, str
* quickly as possible, and let remote TCP know what we have
* received so far. */
if (err == -EAGAIN) {
drbd_tcp_quickack(connection->data.socket);
tcp_sock_set_quickack(connection->data.socket->sk, 2);
drbd_unplug_all_devices(connection);
}
if (err > 0) {
Expand Down Expand Up @@ -4959,8 +4959,7 @@ static int receive_UnplugRemote(struct drbd_connection *connection, struct packe
{
/* Make sure we've acked all the TCP data associated
* with the data requests being unplugged */
drbd_tcp_quickack(connection->data.socket);

tcp_sock_set_quickack(connection->data.socket->sk, 2);
return 0;
}

Expand Down Expand Up @@ -6162,7 +6161,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);
Expand All @@ -6175,7 +6174,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;
}
6 changes: 3 additions & 3 deletions drivers/block/drbd/drbd_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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);
}
Expand Down
42 changes: 9 additions & 33 deletions drivers/infiniband/sw/siw/siw_cm.c
Original file line number Diff line number Diff line change
Expand Up @@ -947,16 +947,8 @@ static void siw_accept_newconn(struct siw_cep *cep)
siw_cep_get(new_cep);
new_s->sk->sk_user_data = new_cep;

if (siw_tcp_nagle == false) {
int val = 1;

rv = kernel_setsockopt(new_s, SOL_TCP, TCP_NODELAY,
(char *)&val, sizeof(val));
if (rv) {
siw_dbg_cep(cep, "setsockopt NODELAY error: %d\n", rv);
goto error;
}
}
if (siw_tcp_nagle == false)
tcp_sock_set_nodelay(new_s->sk);
new_cep->state = SIW_EPSTATE_AWAIT_MPAREQ;

rv = siw_cm_queue_work(new_cep, SIW_CM_WORK_MPATIMEOUT);
Expand Down Expand Up @@ -1312,17 +1304,14 @@ static void siw_cm_llp_state_change(struct sock *sk)
static int kernel_bindconnect(struct socket *s, struct sockaddr *laddr,
struct sockaddr *raddr)
{
int rv, flags = 0, s_val = 1;
int rv, flags = 0;
size_t size = laddr->sa_family == AF_INET ?
sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);

/*
* Make address available again asap.
*/
rv = kernel_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&s_val,
sizeof(s_val));
if (rv < 0)
return rv;
sock_set_reuseaddr(s->sk);

rv = s->ops->bind(s, laddr, size);
if (rv < 0)
Expand Down Expand Up @@ -1389,16 +1378,8 @@ int siw_connect(struct iw_cm_id *id, struct iw_cm_conn_param *params)
siw_dbg_qp(qp, "kernel_bindconnect: error %d\n", rv);
goto error;
}
if (siw_tcp_nagle == false) {
int val = 1;

rv = kernel_setsockopt(s, SOL_TCP, TCP_NODELAY, (char *)&val,
sizeof(val));
if (rv) {
siw_dbg_qp(qp, "setsockopt NODELAY error: %d\n", rv);
goto error;
}
}
if (siw_tcp_nagle == false)
tcp_sock_set_nodelay(s->sk);
cep = siw_cep_alloc(sdev);
if (!cep) {
rv = -ENOMEM;
Expand Down Expand Up @@ -1781,7 +1762,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
struct siw_cep *cep = NULL;
struct siw_device *sdev = to_siw_dev(id->device);
int addr_family = id->local_addr.ss_family;
int rv = 0, s_val;
int rv = 0;

if (addr_family != AF_INET && addr_family != AF_INET6)
return -EAFNOSUPPORT;
Expand All @@ -1793,13 +1774,8 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
/*
* Allow binding local port when still in TIME_WAIT from last close.
*/
s_val = 1;
rv = kernel_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&s_val,
sizeof(s_val));
if (rv) {
siw_dbg(id->device, "setsockopt error: %d\n", rv);
goto error;
}
sock_set_reuseaddr(s->sk);

if (addr_family == AF_INET) {
struct sockaddr_in *laddr = &to_sockaddr_in(id->local_addr);

Expand Down
53 changes: 8 additions & 45 deletions drivers/nvme/host/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1313,8 +1313,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
{
struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
struct nvme_tcp_queue *queue = &ctrl->queues[qid];
struct linger sol = { .l_onoff = 1, .l_linger = 0 };
int ret, opt, rcv_pdu_size;
int ret, rcv_pdu_size;

queue->ctrl = ctrl;
INIT_LIST_HEAD(&queue->send_list);
Expand All @@ -1337,60 +1336,24 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
}

/* Single syn retry */
opt = 1;
ret = kernel_setsockopt(queue->sock, IPPROTO_TCP, TCP_SYNCNT,
(char *)&opt, sizeof(opt));
if (ret) {
dev_err(nctrl->device,
"failed to set TCP_SYNCNT sock opt %d\n", ret);
goto err_sock;
}
tcp_sock_set_syncnt(queue->sock->sk, 1);

/* Set TCP no delay */
opt = 1;
ret = kernel_setsockopt(queue->sock, IPPROTO_TCP,
TCP_NODELAY, (char *)&opt, sizeof(opt));
if (ret) {
dev_err(nctrl->device,
"failed to set TCP_NODELAY sock opt %d\n", ret);
goto err_sock;
}
tcp_sock_set_nodelay(queue->sock->sk);

/*
* Cleanup whatever is sitting in the TCP transmit queue on socket
* close. This is done to prevent stale data from being sent should
* the network connection be restored before TCP times out.
*/
ret = kernel_setsockopt(queue->sock, SOL_SOCKET, SO_LINGER,
(char *)&sol, sizeof(sol));
if (ret) {
dev_err(nctrl->device,
"failed to set SO_LINGER sock opt %d\n", ret);
goto err_sock;
}
sock_no_linger(queue->sock->sk);

if (so_priority > 0) {
ret = kernel_setsockopt(queue->sock, SOL_SOCKET, SO_PRIORITY,
(char *)&so_priority, sizeof(so_priority));
if (ret) {
dev_err(ctrl->ctrl.device,
"failed to set SO_PRIORITY sock opt, ret %d\n",
ret);
goto err_sock;
}
}
if (so_priority > 0)
sock_set_priority(queue->sock->sk, so_priority);

/* Set socket type of service */
if (nctrl->opts->tos >= 0) {
opt = nctrl->opts->tos;
ret = kernel_setsockopt(queue->sock, SOL_IP, IP_TOS,
(char *)&opt, sizeof(opt));
if (ret) {
dev_err(nctrl->device,
"failed to set IP_TOS sock opt %d\n", ret);
goto err_sock;
}
}
if (nctrl->opts->tos >= 0)
ip_sock_set_tos(queue->sock->sk, nctrl->opts->tos);

queue->sock->sk->sk_allocation = GFP_ATOMIC;
nvme_tcp_set_queue_io_cpu(queue);
Expand Down
54 changes: 10 additions & 44 deletions drivers/nvme/target/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1429,7 +1429,6 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
{
struct socket *sock = queue->sock;
struct inet_sock *inet = inet_sk(sock->sk);
struct linger sol = { .l_onoff = 1, .l_linger = 0 };
int ret;

ret = kernel_getsockname(sock,
Expand All @@ -1447,27 +1446,14 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
* close. This is done to prevent stale data from being sent should
* the network connection be restored before TCP times out.
*/
ret = kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
(char *)&sol, sizeof(sol));
if (ret)
return ret;
sock_no_linger(sock->sk);

if (so_priority > 0) {
ret = kernel_setsockopt(sock, SOL_SOCKET, SO_PRIORITY,
(char *)&so_priority, sizeof(so_priority));
if (ret)
return ret;
}
if (so_priority > 0)
sock_set_priority(sock->sk, so_priority);

/* Set socket type of service */
if (inet->rcv_tos > 0) {
int tos = inet->rcv_tos;

ret = kernel_setsockopt(sock, SOL_IP, IP_TOS,
(char *)&tos, sizeof(tos));
if (ret)
return ret;
}
if (inet->rcv_tos > 0)
ip_sock_set_tos(sock->sk, inet->rcv_tos);

write_lock_bh(&sock->sk->sk_callback_lock);
sock->sk->sk_user_data = queue;
Expand Down Expand Up @@ -1588,7 +1574,7 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport)
{
struct nvmet_tcp_port *port;
__kernel_sa_family_t af;
int opt, ret;
int ret;

port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port)
Expand Down Expand Up @@ -1632,30 +1618,10 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport)
port->sock->sk->sk_user_data = port;
port->data_ready = port->sock->sk->sk_data_ready;
port->sock->sk->sk_data_ready = nvmet_tcp_listen_data_ready;

opt = 1;
ret = kernel_setsockopt(port->sock, IPPROTO_TCP,
TCP_NODELAY, (char *)&opt, sizeof(opt));
if (ret) {
pr_err("failed to set TCP_NODELAY sock opt %d\n", ret);
goto err_sock;
}

ret = kernel_setsockopt(port->sock, SOL_SOCKET, SO_REUSEADDR,
(char *)&opt, sizeof(opt));
if (ret) {
pr_err("failed to set SO_REUSEADDR sock opt %d\n", ret);
goto err_sock;
}

if (so_priority > 0) {
ret = kernel_setsockopt(port->sock, SOL_SOCKET, SO_PRIORITY,
(char *)&so_priority, sizeof(so_priority));
if (ret) {
pr_err("failed to set SO_PRIORITY sock opt %d\n", ret);
goto err_sock;
}
}
sock_set_reuseaddr(port->sock->sk);
tcp_sock_set_nodelay(port->sock->sk);
if (so_priority > 0)
sock_set_priority(port->sock->sk, so_priority);

ret = kernel_bind(port->sock, (struct sockaddr *)&port->addr,
sizeof(port->addr));
Expand Down
Loading

0 comments on commit 1e372db

Please sign in to comment.