Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cd967e05 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

netlink: add symbolic value for congested state

parent 447b816f
Loading
Loading
Loading
Loading
+11 −7
Original line number Original line Diff line number Diff line
@@ -68,6 +68,10 @@ struct listeners {
	unsigned long		masks[0];
	unsigned long		masks[0];
};
};


/* state bits */
#define NETLINK_CONGESTED	0x0

/* flags */
#define NETLINK_KERNEL_SOCKET	0x1
#define NETLINK_KERNEL_SOCKET	0x1
#define NETLINK_RECV_PKTINFO	0x2
#define NETLINK_RECV_PKTINFO	0x2
#define NETLINK_BROADCAST_SEND_ERROR	0x4
#define NETLINK_BROADCAST_SEND_ERROR	0x4
@@ -727,7 +731,7 @@ static void netlink_overrun(struct sock *sk)
	struct netlink_sock *nlk = nlk_sk(sk);
	struct netlink_sock *nlk = nlk_sk(sk);


	if (!(nlk->flags & NETLINK_RECV_NO_ENOBUFS)) {
	if (!(nlk->flags & NETLINK_RECV_NO_ENOBUFS)) {
		if (!test_and_set_bit(0, &nlk_sk(sk)->state)) {
		if (!test_and_set_bit(NETLINK_CONGESTED, &nlk_sk(sk)->state)) {
			sk->sk_err = ENOBUFS;
			sk->sk_err = ENOBUFS;
			sk->sk_error_report(sk);
			sk->sk_error_report(sk);
		}
		}
@@ -788,7 +792,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
	nlk = nlk_sk(sk);
	nlk = nlk_sk(sk);


	if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
	if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
	    test_bit(0, &nlk->state)) {
	    test_bit(NETLINK_CONGESTED, &nlk->state)) {
		DECLARE_WAITQUEUE(wait, current);
		DECLARE_WAITQUEUE(wait, current);
		if (!*timeo) {
		if (!*timeo) {
			if (!ssk || netlink_is_kernel(ssk))
			if (!ssk || netlink_is_kernel(ssk))
@@ -802,7 +806,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
		add_wait_queue(&nlk->wait, &wait);
		add_wait_queue(&nlk->wait, &wait);


		if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
		if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
		     test_bit(0, &nlk->state)) &&
		     test_bit(NETLINK_CONGESTED, &nlk->state)) &&
		    !sock_flag(sk, SOCK_DEAD))
		    !sock_flag(sk, SOCK_DEAD))
			*timeo = schedule_timeout(*timeo);
			*timeo = schedule_timeout(*timeo);


@@ -872,8 +876,8 @@ static void netlink_rcv_wake(struct sock *sk)
	struct netlink_sock *nlk = nlk_sk(sk);
	struct netlink_sock *nlk = nlk_sk(sk);


	if (skb_queue_empty(&sk->sk_receive_queue))
	if (skb_queue_empty(&sk->sk_receive_queue))
		clear_bit(0, &nlk->state);
		clear_bit(NETLINK_CONGESTED, &nlk->state);
	if (!test_bit(0, &nlk->state))
	if (!test_bit(NETLINK_CONGESTED, &nlk->state))
		wake_up_interruptible(&nlk->wait);
		wake_up_interruptible(&nlk->wait);
}
}


@@ -957,7 +961,7 @@ static int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb)
	struct netlink_sock *nlk = nlk_sk(sk);
	struct netlink_sock *nlk = nlk_sk(sk);


	if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
	if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
	    !test_bit(0, &nlk->state)) {
	    !test_bit(NETLINK_CONGESTED, &nlk->state)) {
		skb_set_owner_r(skb, sk);
		skb_set_owner_r(skb, sk);
		__netlink_sendskb(sk, skb);
		__netlink_sendskb(sk, skb);
		return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
		return atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1);
@@ -1235,7 +1239,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
	case NETLINK_NO_ENOBUFS:
	case NETLINK_NO_ENOBUFS:
		if (val) {
		if (val) {
			nlk->flags |= NETLINK_RECV_NO_ENOBUFS;
			nlk->flags |= NETLINK_RECV_NO_ENOBUFS;
			clear_bit(0, &nlk->state);
			clear_bit(NETLINK_CONGESTED, &nlk->state);
			wake_up_interruptible(&nlk->wait);
			wake_up_interruptible(&nlk->wait);
		} else {
		} else {
			nlk->flags &= ~NETLINK_RECV_NO_ENOBUFS;
			nlk->flags &= ~NETLINK_RECV_NO_ENOBUFS;