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

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
Loading
Loading
Loading
Loading
+3 −11
Original line number Diff line number Diff line
@@ -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_queue *queue = &ctrl->queues[qid];
	int ret, opt, rcv_pdu_size;
	int ret, rcv_pdu_size;

	queue->ctrl = ctrl;
	INIT_LIST_HEAD(&queue->send_list);
@@ -1352,16 +1352,8 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl,
		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);
+2 −8
Original line number Diff line number Diff line
@@ -1452,14 +1452,8 @@ static int nvmet_tcp_set_queue_sock(struct nvmet_tcp_queue *queue)
		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;
+2 −0
Original line number Diff line number Diff line
@@ -765,4 +765,6 @@ static inline bool inetdev_valid_mtu(unsigned int mtu)
	return likely(mtu >= IPV4_MIN_MTU);
}

void ip_sock_set_tos(struct sock *sk, int val);

#endif	/* _IP_H */
+21 −9
Original line number Diff line number Diff line
@@ -560,6 +560,26 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
	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
@@ -823,15 +843,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
			inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE;
		break;
	case IP_TOS:	/* This sets both TOS and Precedence */
		if (sk->sk_type == SOCK_STREAM) {
			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);
		}
		__ip_sock_set_tos(sk, val);
		break;
	case IP_TTL:
		if (optlen < 1)