Commit 6ebf71ba authored by Christoph Hellwig's avatar Christoph Hellwig Committed by David S. Miller

ipv4: add ip_sock_set_tos

Add a helper to directly set the IP_TOS sockopt from kernel space without
going through a fake uaccess.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Acked-by: default avatarSagi Grimberg <sagi@grimberg.me>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 480aeb96
...@@ -1313,7 +1313,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, ...@@ -1313,7 +1313,7 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
{ {
struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
struct nvme_tcp_queue *queue = &ctrl->queues[qid]; struct nvme_tcp_queue *queue = &ctrl->queues[qid];
int ret, opt, rcv_pdu_size; int ret, rcv_pdu_size;
queue->ctrl = ctrl; queue->ctrl = ctrl;
INIT_LIST_HEAD(&queue->send_list); INIT_LIST_HEAD(&queue->send_list);
...@@ -1352,16 +1352,8 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, ...@@ -1352,16 +1352,8 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
sock_set_priority(queue->sock->sk, so_priority); sock_set_priority(queue->sock->sk, so_priority);
/* Set socket type of service */ /* Set socket type of service */
if (nctrl->opts->tos >= 0) { if (nctrl->opts->tos >= 0)
opt = nctrl->opts->tos; ip_sock_set_tos(queue->sock->sk, 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;
}
}
queue->sock->sk->sk_allocation = GFP_ATOMIC; queue->sock->sk->sk_allocation = GFP_ATOMIC;
nvme_tcp_set_queue_io_cpu(queue); nvme_tcp_set_queue_io_cpu(queue);
......
...@@ -1452,14 +1452,8 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue) ...@@ -1452,14 +1452,8 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
sock_set_priority(sock->sk, so_priority); sock_set_priority(sock->sk, so_priority);
/* Set socket type of service */ /* Set socket type of service */
if (inet->rcv_tos > 0) { if (inet->rcv_tos > 0)
int tos = inet->rcv_tos; ip_sock_set_tos(sock->sk, inet->rcv_tos);
ret = kernel_setsockopt(sock, SOL_IP, IP_TOS,
(char *)&tos, sizeof(tos));
if (ret)
return ret;
}
write_lock_bh(&sock->sk->sk_callback_lock); write_lock_bh(&sock->sk->sk_callback_lock);
sock->sk->sk_user_data = queue; sock->sk->sk_user_data = queue;
......
...@@ -765,4 +765,6 @@ static inline bool inetdev_valid_mtu(unsigned int mtu) ...@@ -765,4 +765,6 @@ static inline bool inetdev_valid_mtu(unsigned int mtu)
return likely(mtu >= IPV4_MIN_MTU); return likely(mtu >= IPV4_MIN_MTU);
} }
void ip_sock_set_tos(struct sock *sk, int val);
#endif /* _IP_H */ #endif /* _IP_H */
...@@ -560,6 +560,26 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) ...@@ -560,6 +560,26 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
return err; return err;
} }
static void __ip_sock_set_tos(struct sock *sk, int val)
{
if (sk->sk_type == SOCK_STREAM) {
val &= ~INET_ECN_MASK;
val |= inet_sk(sk)->tos & INET_ECN_MASK;
}
if (inet_sk(sk)->tos != val) {
inet_sk(sk)->tos = val;
sk->sk_priority = rt_tos2priority(val);
sk_dst_reset(sk);
}
}
void ip_sock_set_tos(struct sock *sk, int val)
{
lock_sock(sk);
__ip_sock_set_tos(sk, val);
release_sock(sk);
}
EXPORT_SYMBOL(ip_sock_set_tos);
/* /*
* Socket option code for IP. This is the end of the line after any * Socket option code for IP. This is the end of the line after any
...@@ -823,15 +843,7 @@ static int do_ip_setsockopt(struct sock *sk, int level, ...@@ -823,15 +843,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE; inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE;
break; break;
case IP_TOS: /* This sets both TOS and Precedence */ case IP_TOS: /* This sets both TOS and Precedence */
if (sk->sk_type == SOCK_STREAM) { __ip_sock_set_tos(sk, val);
val &= ~INET_ECN_MASK;
val |= inet->tos & INET_ECN_MASK;
}
if (inet->tos != val) {
inet->tos = val;
sk->sk_priority = rt_tos2priority(val);
sk_dst_reset(sk);
}
break; break;
case IP_TTL: case IP_TTL:
if (optlen < 1) if (optlen < 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment