summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2017-11-10 08:55:50 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2017-11-10 08:55:50 +0000
commita7e0f9f7479a745597fd997b19c765e50331e34c (patch)
tree00cb6afde8cc223a654e3e046fb1fbf2dfcd3b57
parent5c2327cf27ca4fe7d184ee526ce95275b52304de (diff)
Introduce a reader version of the NET_LOCK().
This will be used to first allow read-only ioctl(2) to be executed while the softnet taskq is running. Then it will allows us to execute multiple softnet taskq in parallel. Tested by Hrvoje Popovski, ok kettenis@, sashan@, visa@, tb@
-rw-r--r--sys/net/if.c6
-rw-r--r--sys/netinet/ip_input.c6
-rw-r--r--sys/netinet6/ip6_input.c6
-rw-r--r--sys/sys/systm.h36
4 files changed, 32 insertions, 22 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 626a7922a12..3bdd998fc7b 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.524 2017/11/09 09:07:01 tb Exp $ */
+/* $OpenBSD: if.c,v 1.525 2017/11/10 08:55:49 mpi Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -906,7 +906,7 @@ if_input_process(void *xifidx)
* to PF globals, pipex globals, unicast and multicast addresses
* lists.
*/
- NET_LOCK();
+ NET_RLOCK();
s = splnet();
while ((m = ml_dequeue(&ml)) != NULL) {
/*
@@ -923,7 +923,7 @@ if_input_process(void *xifidx)
m_freem(m);
}
splx(s);
- NET_UNLOCK();
+ NET_RUNLOCK();
out:
if_put(ifp);
}
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index bb6940a7a07..238ab79df32 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.330 2017/11/08 16:29:20 visa Exp $ */
+/* $OpenBSD: ip_input.c,v 1.331 2017/11/10 08:55:49 mpi Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -1818,11 +1818,11 @@ ip_send_dispatch(void *xmq)
if (ml_empty(&ml))
return;
- NET_LOCK();
+ NET_RLOCK();
while ((m = ml_dequeue(&ml)) != NULL) {
ip_output(m, NULL, NULL, 0, NULL, NULL, 0);
}
- NET_UNLOCK();
+ NET_RUNLOCK();
}
void
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index f106d0a3250..caf6dfeb23b 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.207 2017/11/01 06:35:38 mpi Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.208 2017/11/10 08:55:49 mpi Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -1459,7 +1459,7 @@ ip6_send_dispatch(void *xmq)
if (ml_empty(&ml))
return;
- NET_LOCK();
+ NET_RLOCK();
while ((m = ml_dequeue(&ml)) != NULL) {
/*
* To avoid a "too big" situation at an intermediate router and
@@ -1470,7 +1470,7 @@ ip6_send_dispatch(void *xmq)
*/
ip6_output(m, NULL, NULL, IPV6_MINMTU, NULL, NULL);
}
- NET_UNLOCK();
+ NET_RUNLOCK();
}
void
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 7a4c2fa2ed4..ba836006091 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: systm.h,v 1.133 2017/08/11 21:24:20 mpi Exp $ */
+/* $OpenBSD: systm.h,v 1.134 2017/11/10 08:55:49 mpi Exp $ */
/* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */
/*-
@@ -296,26 +296,36 @@ int uiomove(void *, size_t, struct uio *);
extern struct rwlock netlock;
-#define NET_LOCK() \
-do { \
- rw_enter_write(&netlock); \
-} while (0)
+#define NET_LOCK() NET_WLOCK()
+#define NET_UNLOCK() NET_WUNLOCK()
+#define NET_ASSERT_UNLOCKED() NET_ASSERT_WUNLOCKED()
+
+
+#define NET_WLOCK() do { rw_enter_write(&netlock); } while (0)
+#define NET_WUNLOCK() do { rw_exit_write(&netlock); } while (0)
-#define NET_UNLOCK() \
+#define NET_ASSERT_WLOCKED() \
do { \
- rw_exit_write(&netlock); \
+ int _s = rw_status(&netlock); \
+ if (_s != RW_WRITE) \
+ splassert_fail(RW_WRITE, _s, __func__); \
} while (0)
-#define NET_ASSERT_LOCKED() \
+#define NET_ASSERT_WUNLOCKED() \
do { \
- if (rw_status(&netlock) != RW_WRITE) \
- splassert_fail(RW_WRITE, rw_status(&netlock), __func__);\
+ int _s = rw_status(&netlock); \
+ if (_s == RW_WRITE) \
+ splassert_fail(0, RW_WRITE, __func__); \
} while (0)
-#define NET_ASSERT_UNLOCKED() \
+#define NET_RLOCK() do { rw_enter_read(&netlock); } while (0)
+#define NET_RUNLOCK() do { rw_exit_read(&netlock); } while (0)
+
+#define NET_ASSERT_LOCKED() \
do { \
- if (rw_status(&netlock) == RW_WRITE) \
- splassert_fail(0, rw_status(&netlock), __func__); \
+ int _s = rw_status(&netlock); \
+ if (_s != RW_WRITE && _s != RW_READ) \
+ splassert_fail(RW_READ, _s, __func__); \
} while (0)
__returns_twice int setjmp(label_t *);