netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin LaHaise <bcrl@redhat.com>
To: davem@redhat.com, netdev@oss.sgi.com
Subject: [patch] abstract out socket lock.users access
Date: Mon, 7 Oct 2002 17:55:51 -0400	[thread overview]
Message-ID: <20021007175551.B30693@redhat.com> (raw)

Hello Dave et al,

The patch below abstracts out accesses of the socket lock users count access 
and replaces it with a macro, is_sock_locked(sk).  It also changes 
sk->lock.users into a .owner field that stores a pointer to the current 
iocb that owns the lock.  This is useful for aio as the userland side of a 
socket lock may need to be held until an operation that would have blocked 
is retried.  Comments?

		-ben

:r ~/patches/v2.5/v2.5.41-net-is_locked.diff
diff -urN v2.5.41/include/net/sock.h linux.net-aio.00/include/net/sock.h
--- v2.5.41/include/net/sock.h	Tue Oct  1 13:25:11 2002
+++ linux.net-aio.00/include/net/sock.h	Mon Oct  7 17:27:07 2002
@@ -70,15 +70,16 @@
  * between user contexts and software interrupt processing, whereas the
  * mini-semaphore synchronizes multiple users amongst themselves.
  */
+struct sock_iocb;
 typedef struct {
 	spinlock_t		slock;
-	unsigned int		users;
+	struct sock_iocb	*owner;
 	wait_queue_head_t	wq;
 } socket_lock_t;
 
 #define sock_lock_init(__sk) \
 do {	spin_lock_init(&((__sk)->lock.slock)); \
-	(__sk)->lock.users = 0; \
+	(__sk)->lock.owner = NULL; \
 	init_waitqueue_head(&((__sk)->lock.wq)); \
 } while(0)
 
@@ -306,22 +307,35 @@
  * Since ~2.3.5 it is also exclusive sleep lock serializing
  * accesses from user process context.
  */
+extern int __async_lock_sock(struct sock_iocb *, struct sock *, struct list_head *);
 extern void __lock_sock(struct sock *sk);
 extern void __release_sock(struct sock *sk);
+#define sock_is_locked(sk)	(NULL != (sk)->lock.owner)
 #define lock_sock(__sk) \
 do {	might_sleep(); \
 	spin_lock_bh(&((__sk)->lock.slock)); \
-	if ((__sk)->lock.users != 0) \
+	if ((__sk)->lock.owner != NULL) \
 		__lock_sock(__sk); \
-	(__sk)->lock.users = 1; \
+	(__sk)->lock.owner = (void *)1; \
 	spin_unlock_bh(&((__sk)->lock.slock)); \
 } while(0)
 
+#define async_lock_sock(iocb, __sk, list) \
+({	int ret = 0; \
+	spin_lock_bh(&((__sk)->lock.slock)); \
+	if ((__sk)->lock.owner != NULL) \
+		ret = __async_lock_sock((iocb), (__sk), (list)); \
+	else \
+		(__sk)->lock.owner = (iocb); \
+	spin_unlock_bh(&((__sk)->lock.slock)); \
+	ret; \
+})
+
 #define release_sock(__sk) \
 do {	spin_lock_bh(&((__sk)->lock.slock)); \
 	if ((__sk)->backlog.tail != NULL) \
 		__release_sock(__sk); \
-	(__sk)->lock.users = 0; \
+	(__sk)->lock.owner = NULL; \
         if (waitqueue_active(&((__sk)->lock.wq))) wake_up(&((__sk)->lock.wq)); \
 	spin_unlock_bh(&((__sk)->lock.slock)); \
 } while(0)
diff -urN v2.5.41/include/net/tcp.h linux.net-aio.00/include/net/tcp.h
--- v2.5.41/include/net/tcp.h	Tue Sep 17 18:05:36 2002
+++ linux.net-aio.00/include/net/tcp.h	Mon Oct  7 17:20:05 2002
@@ -1348,7 +1348,7 @@
 		if (tp->ucopy.memory > sk->rcvbuf) {
 			struct sk_buff *skb1;
 
-			if (sk->lock.users) BUG();
+			if (sock_is_locked(sk)) BUG();
 
 			while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
 				sk->backlog_rcv(sk, skb1);
diff -urN v2.5.41/net/core/sock.c linux.net-aio.00/net/core/sock.c
--- v2.5.41/net/core/sock.c	Tue Sep 17 18:05:38 2002
+++ linux.net-aio.00/net/core/sock.c	Mon Oct  7 17:20:05 2002
@@ -861,7 +861,7 @@
 		spin_unlock_bh(&sk->lock.slock);
 		schedule();
 		spin_lock_bh(&sk->lock.slock);
-		if(!sk->lock.users)
+		if(!sock_is_locked(sk))
 			break;
 	}
 	current->state = TASK_RUNNING;
diff -urN v2.5.41/net/decnet/dn_nsp_in.c linux.net-aio.00/net/decnet/dn_nsp_in.c
--- v2.5.41/net/decnet/dn_nsp_in.c	Thu Jun  6 00:35:20 2002
+++ linux.net-aio.00/net/decnet/dn_nsp_in.c	Mon Oct  7 17:32:49 2002
@@ -800,8 +800,8 @@
 			printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n",
 				(int)cb->rt_flags, (int)cb->nsp_flags, 
 				(int)cb->src_port, (int)cb->dst_port, 
-				(int)sk->lock.users);
-		if (sk->lock.users == 0)
+				(int)is_sock_locked(sk));
+		if (!is_sock_locked(sk))
 			ret = dn_nsp_backlog_rcv(sk, skb);
 		else
 			sk_add_backlog(sk, skb);
diff -urN v2.5.41/net/decnet/dn_timer.c linux.net-aio.00/net/decnet/dn_timer.c
--- v2.5.41/net/decnet/dn_timer.c	Mon Jan 22 16:32:10 2001
+++ linux.net-aio.00/net/decnet/dn_timer.c	Mon Oct  7 17:33:38 2002
@@ -57,7 +57,7 @@
 	sock_hold(sk);
 	bh_lock_sock(sk);
 
-	if (sk->lock.users != 0) {
+	if (is_sock_locked(sk)) {
 		sk->timer.expires = jiffies + HZ / 10;
 		add_timer(&sk->timer);
 		goto out;
@@ -115,7 +115,7 @@
 	struct dn_scp *scp = DN_SK(sk);
 
 	bh_lock_sock(sk);
-	if (sk->lock.users != 0) {
+	if (is_sock_locked(sk)) {
 		scp->delack_timer.expires = jiffies + HZ / 20;
 		add_timer(&scp->delack_timer);
 		goto out;
diff -urN v2.5.41/net/ipv4/tcp.c linux.net-aio.00/net/ipv4/tcp.c
--- v2.5.41/net/ipv4/tcp.c	Tue Sep  3 19:47:24 2002
+++ linux.net-aio.00/net/ipv4/tcp.c	Mon Oct  7 17:20:05 2002
@@ -623,7 +623,7 @@
 
 		local_bh_disable();
 		bh_lock_sock(child);
-		BUG_TRAP(!child->lock.users);
+		BUG_TRAP(!sock_is_locked(child));
 		sock_hold(child);
 
 		tcp_disconnect(child, O_NONBLOCK);
@@ -2019,7 +2019,7 @@
 	 */
 	local_bh_disable();
 	bh_lock_sock(sk);
-	BUG_TRAP(!sk->lock.users);
+	BUG_TRAP(!sock_is_locked(sk));
 
 	sock_hold(sk);
 	sock_orphan(sk);
diff -urN v2.5.41/net/ipv4/tcp_input.c linux.net-aio.00/net/ipv4/tcp_input.c
--- v2.5.41/net/ipv4/tcp_input.c	Mon Oct  7 17:19:22 2002
+++ linux.net-aio.00/net/ipv4/tcp_input.c	Mon Oct  7 17:20:05 2002
@@ -2570,7 +2570,7 @@
 		/* Ok. In sequence. In window. */
 		if (tp->ucopy.task == current &&
 		    tp->copied_seq == tp->rcv_nxt && tp->ucopy.len &&
-		    sk->lock.users && !tp->urg_data) {
+		    sock_is_locked(sk) && !tp->urg_data) {
 			int chunk = min_t(unsigned int, skb->len,
 							tp->ucopy.len);
 
@@ -3190,7 +3190,7 @@
 {
 	int result;
 
-	if (sk->lock.users) {
+	if (sock_is_locked(sk)) {
 		local_bh_enable();
 		result = __tcp_checksum_complete(skb);
 		local_bh_disable();
@@ -3324,7 +3324,7 @@
 			if (tp->ucopy.task == current &&
 			    tp->copied_seq == tp->rcv_nxt &&
 			    len - tcp_header_len <= tp->ucopy.len &&
-			    sk->lock.users) {
+			    sock_is_locked(sk)) {
 				__set_current_state(TASK_RUNNING);
 
 				if (!tcp_copy_to_iovec(sk, skb, tcp_header_len)) {
@@ -3864,7 +3864,7 @@
 					tmo = tcp_fin_time(tp);
 					if (tmo > TCP_TIMEWAIT_LEN) {
 						tcp_reset_keepalive_timer(sk, tmo - TCP_TIMEWAIT_LEN);
-					} else if (th->fin || sk->lock.users) {
+					} else if (th->fin || sock_is_locked(sk)) {
 						/* Bad case. We could lose such FIN otherwise.
 						 * It is not a big problem, but it looks confusing
 						 * and not so rare event. We still can lose it now,
diff -urN v2.5.41/net/ipv4/tcp_ipv4.c linux.net-aio.00/net/ipv4/tcp_ipv4.c
--- v2.5.41/net/ipv4/tcp_ipv4.c	Mon Oct  7 17:19:22 2002
+++ linux.net-aio.00/net/ipv4/tcp_ipv4.c	Mon Oct  7 17:20:05 2002
@@ -1003,7 +1003,7 @@
 	/* If too many ICMPs get dropped on busy
 	 * servers this needs to be solved differently.
 	 */
-	if (sk->lock.users)
+	if (sock_is_locked(sk))
 		NET_INC_STATS_BH(LockDroppedIcmps);
 
 	if (sk->state == TCP_CLOSE)
@@ -1022,7 +1022,7 @@
 		/* This is deprecated, but if someone generated it,
 		 * we have no reasons to ignore it.
 		 */
-		if (!sk->lock.users)
+		if (!sock_is_locked(sk))
 			tcp_enter_cwr(tp);
 		goto out;
 	case ICMP_PARAMETERPROB:
@@ -1033,7 +1033,7 @@
 			goto out;
 
 		if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
-			if (!sk->lock.users)
+			if (!sock_is_locked(sk))
 				do_pmtu_discovery(sk, iph, info);
 			goto out;
 		}
@@ -1050,7 +1050,7 @@
 	switch (sk->state) {
 		struct open_request *req, **prev;
 	case TCP_LISTEN:
-		if (sk->lock.users)
+		if (sock_is_locked(sk))
 			goto out;
 
 		req = tcp_v4_search_req(tp, &prev, th->dest,
@@ -1081,7 +1081,7 @@
 	case TCP_SYN_RECV:  /* Cannot happen.
 			       It can f.e. if SYNs crossed.
 			     */
-		if (!sk->lock.users) {
+		if (!sock_is_locked(sk)) {
 			TCP_INC_STATS_BH(TcpAttemptFails);
 			sk->err = err;
 
@@ -1111,7 +1111,7 @@
 	 */
 
 	inet = inet_sk(sk);
-	if (!sk->lock.users && inet->recverr) {
+	if (!sock_is_locked(sk) && inet->recverr) {
 		sk->err = err;
 		sk->error_report(sk);
 	} else	{ /* Only an error on timeout */
@@ -1778,7 +1778,7 @@
 
 	bh_lock_sock(sk);
 	ret = 0;
-	if (!sk->lock.users) {
+	if (!sock_is_locked(sk)) {
 		if (!tcp_prequeue(sk, skb))
 			ret = tcp_v4_do_rcv(sk, skb);
 	} else
diff -urN v2.5.41/net/ipv4/tcp_minisocks.c linux.net-aio.00/net/ipv4/tcp_minisocks.c
--- v2.5.41/net/ipv4/tcp_minisocks.c	Mon Oct  7 17:19:22 2002
+++ linux.net-aio.00/net/ipv4/tcp_minisocks.c	Mon Oct  7 17:20:05 2002
@@ -989,7 +989,7 @@
 	int ret = 0;
 	int state = child->state;
 
-	if (child->lock.users == 0) {
+	if (!sock_is_locked(child)) {
 		ret = tcp_rcv_state_process(child, skb, skb->h.th, skb->len);
 
 		/* Wakeup parent, send SIGIO */
diff -urN v2.5.41/net/ipv4/tcp_timer.c linux.net-aio.00/net/ipv4/tcp_timer.c
--- v2.5.41/net/ipv4/tcp_timer.c	Thu Jun  6 00:35:29 2002
+++ linux.net-aio.00/net/ipv4/tcp_timer.c	Mon Oct  7 17:20:05 2002
@@ -213,7 +213,7 @@
 	struct tcp_opt *tp = tcp_sk(sk);
 
 	bh_lock_sock(sk);
-	if (sk->lock.users) {
+	if (sock_is_locked(sk)) {
 		/* Try again later. */
 		tp->ack.blocked = 1;
 		NET_INC_STATS_BH(DelayedACKLocked);
@@ -421,7 +421,7 @@
 	int event;
 
 	bh_lock_sock(sk);
-	if (sk->lock.users) {
+	if (sock_is_locked(sk)) {
 		/* Try again later */
 		if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20)))
 			sock_hold(sk);
@@ -581,7 +581,7 @@
 
 	/* Only process if socket is not in use. */
 	bh_lock_sock(sk);
-	if (sk->lock.users) {
+	if (sock_is_locked(sk)) {
 		/* Try again later. */ 
 		tcp_reset_keepalive_timer (sk, HZ/20);
 		goto out;
diff -urN v2.5.41/net/ipv6/tcp_ipv6.c linux.net-aio.00/net/ipv6/tcp_ipv6.c
--- v2.5.41/net/ipv6/tcp_ipv6.c	Tue Sep  3 19:47:24 2002
+++ linux.net-aio.00/net/ipv6/tcp_ipv6.c	Mon Oct  7 17:35:17 2002
@@ -731,7 +731,7 @@
 	}
 
 	bh_lock_sock(sk);
-	if (sk->lock.users)
+	if (is_sock_locked(sk))
 		NET_INC_STATS_BH(LockDroppedIcmps);
 
 	if (sk->state == TCP_CLOSE)
@@ -749,7 +749,7 @@
 	if (type == ICMPV6_PKT_TOOBIG) {
 		struct dst_entry *dst = NULL;
 
-		if (sk->lock.users)
+		if (is_sock_locked(sk))
 			goto out;
 		if ((1<<sk->state)&(TCPF_LISTEN|TCPF_CLOSE))
 			goto out;
@@ -792,7 +792,7 @@
 	switch (sk->state) {
 		struct open_request *req, **prev;
 	case TCP_LISTEN:
-		if (sk->lock.users)
+		if (is_sock_locked(sk))
 			goto out;
 
 		req = tcp_v6_search_req(tp, &prev, th->dest, &hdr->daddr,
@@ -816,7 +816,7 @@
 	case TCP_SYN_SENT:
 	case TCP_SYN_RECV:  /* Cannot happen.
 			       It can, it SYNs are crossed. --ANK */ 
-		if (sk->lock.users == 0) {
+		if (!is_sock_locked(sk)) {
 			TCP_INC_STATS_BH(TcpAttemptFails);
 			sk->err = err;
 			sk->error_report(sk);		/* Wake people up to see the error (see connect in sock.c) */
@@ -828,7 +828,7 @@
 		goto out;
 	}
 
-	if (sk->lock.users == 0 && np->recverr) {
+	if (!is_sock_locked(sk) && np->recverr) {
 		sk->err = err;
 		sk->error_report(sk);
 	} else {
@@ -1622,7 +1622,7 @@
 
 	bh_lock_sock(sk);
 	ret = 0;
-	if (!sk->lock.users) {
+	if (!is_sock_locked(sk)) {
 		if (!tcp_prequeue(sk, skb))
 			ret = tcp_v6_do_rcv(sk, skb);
 	} else
diff -urN v2.5.41/net/llc/llc_c_ac.c linux.net-aio.00/net/llc/llc_c_ac.c
--- v2.5.41/net/llc/llc_c_ac.c	Mon Oct  7 17:19:22 2002
+++ linux.net-aio.00/net/llc/llc_c_ac.c	Mon Oct  7 17:35:35 2002
@@ -1489,7 +1489,7 @@
 		       __FUNCTION__);
 		kfree_skb(skb);
 	} else {
-		if (!sk->lock.users)
+		if (!is_sock_locked(sk))
 			llc_conn_state_process(sk, skb);
 		else {
 			llc_set_backlog_type(skb, LLC_EVENT);
diff -urN v2.5.41/net/llc/llc_mac.c linux.net-aio.00/net/llc/llc_mac.c
--- v2.5.41/net/llc/llc_mac.c	Mon Oct  7 17:19:22 2002
+++ linux.net-aio.00/net/llc/llc_mac.c	Mon Oct  7 17:35:55 2002
@@ -140,7 +140,7 @@
 		} else
 			skb->sk = sk;
 		bh_lock_sock(sk);
-		if (!sk->lock.users) {
+		if (!is_sock_locked(sk)) {
 			/* rc = */ llc_conn_rcv(sk, skb);
 			rc = 0;
 		} else {
diff -urN v2.5.41/net/llc/llc_proc.c linux.net-aio.00/net/llc/llc_proc.c
--- v2.5.41/net/llc/llc_proc.c	Mon Oct  7 17:19:22 2002
+++ linux.net-aio.00/net/llc/llc_proc.c	Mon Oct  7 17:36:15 2002
@@ -182,7 +182,7 @@
 		   timer_pending(&llc->pf_cycle_timer.timer),
 		   timer_pending(&llc->rej_sent_timer.timer),
 		   timer_pending(&llc->busy_state_timer.timer),
-		   !!sk->backlog.tail, sk->lock.users);
+		   !!sk->backlog.tail, is_sock_locked(sk));
 out:
 	return 0;
 }
diff -urN v2.5.41/net/x25/x25_dev.c linux.net-aio.00/net/x25/x25_dev.c
--- v2.5.41/net/x25/x25_dev.c	Tue Oct  1 13:25:11 2002
+++ linux.net-aio.00/net/x25/x25_dev.c	Mon Oct  7 17:36:32 2002
@@ -70,7 +70,7 @@
 
 		skb->h.raw = skb->data;
 		bh_lock_sock(sk);
-		if (!sk->lock.users) {
+		if (!is_sock_locked(sk)) {
 			queued = x25_process_rx_frame(sk, skb);
 		} else {
 			sk_add_backlog(sk, skb);
diff -urN v2.5.41/net/x25/x25_timer.c linux.net-aio.00/net/x25/x25_timer.c
--- v2.5.41/net/x25/x25_timer.c	Tue Oct  1 13:25:11 2002
+++ linux.net-aio.00/net/x25/x25_timer.c	Mon Oct  7 17:36:55 2002
@@ -131,7 +131,7 @@
 	struct sock *sk = (struct sock *)param;
 
         bh_lock_sock(sk);
-        if (sk->lock.users) /* can currently only occur in state 3 */ 
+        if (is_sock_locked(sk)) /* can currently only occur in state 3 */ 
 		goto restart_heartbeat;
 
 	switch (x25_sk(sk)->state) {
@@ -193,7 +193,7 @@
 	struct sock *sk = (struct sock *)param;
 
 	bh_lock_sock(sk);
-	if (sk->lock.users) { /* can currently only occur in state 3 */
+	if (is_sock_locked(sk)) { /* can currently only occur in state 3 */
 		if (x25_sk(sk)->state == X25_STATE_3)
 			x25_start_t2timer(sk);
 	} else

             reply	other threads:[~2002-10-07 21:55 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-10-07 21:55 Benjamin LaHaise [this message]
2002-10-07 22:14 ` [patch] abstract out socket lock.users access David S. Miller
2002-10-07 22:50   ` Benjamin LaHaise
2002-10-07 22:53     ` David S. Miller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20021007175551.B30693@redhat.com \
    --to=bcrl@redhat.com \
    --cc=davem@redhat.com \
    --cc=netdev@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).