Hello,
just for the record...
</snip>
> > in current tree the ether_input() is protected by NET_LOCK(), which is
> > grabbed
> > by caller as a writer. bluhm's diff changes NET_LOCK() readlock, so
> > ether_input() can run concurrently. Switching NET_LOCK() to r-lock has
> > implications on smr read section above. The ting is the call to
> > eb->eb_input()
> > can sleep now. This is something what needs to be avoided within smr
> > section.
>
> Is the new sleeping point introduced by the fact the PF_LOCK() is a
> rwlock? Did you consider using a mutex, at least for the time being,
> in order to not run in such issues?
below is a diff, which trades both pf(4) rw-locks for mutexes.
diff compiles, it still needs testing/experimenting.
regards
sashan
--------8<---------------8<---------------8<------------------8<--------
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index ae7bb008351..30c78da7d16 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -146,8 +146,8 @@ TAILQ_HEAD(pf_tags, pf_tagname) pf_tags =
TAILQ_HEAD_INITIALIZER(pf_tags),
* grab the lock as writer. Whenever packet creates state it grabs pf_lock
* first then it locks pf_state_lock as the writer.
*/
-struct rwlock pf_lock = RWLOCK_INITIALIZER("pf_lock");
-struct rwlock pf_state_lock = RWLOCK_INITIALIZER("pf_state_lock");
+struct mutex pf_lock = MUTEX_INITIALIZER(IPL_NET);
+struct mutex pf_state_lock = MUTEX_INITIALIZER(IPL_NET);
#if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
#error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
diff --git a/sys/net/pfvar_priv.h b/sys/net/pfvar_priv.h
index b1a122af409..c5ae392b468 100644
--- a/sys/net/pfvar_priv.h
+++ b/sys/net/pfvar_priv.h
@@ -39,7 +39,7 @@
#include <sys/rwlock.h>
-extern struct rwlock pf_lock;
+extern struct mutex pf_lock;
struct pf_pdesc {
struct {
@@ -104,52 +104,41 @@ extern struct timeout pf_purge_to;
struct pf_state *pf_state_ref(struct pf_state *);
void pf_state_unref(struct pf_state *);
-extern struct rwlock pf_lock;
-extern struct rwlock pf_state_lock;
+extern struct mutex pf_lock;
+extern struct mutex pf_state_lock;
#define PF_LOCK() do { \
NET_ASSERT_LOCKED(); \
- rw_enter_write(&pf_lock); \
+ mtx_enter(&pf_lock); \
} while (0)
#define PF_UNLOCK() do { \
PF_ASSERT_LOCKED(); \
- rw_exit_write(&pf_lock); \
+ mtx_leave(&pf_lock); \
} while (0)
-#define PF_ASSERT_LOCKED() do { \
- if (rw_status(&pf_lock) != RW_WRITE) \
- splassert_fail(RW_WRITE, \
- rw_status(&pf_lock),__func__);\
- } while (0)
+#define PF_ASSERT_LOCKED() (void)(0)
-#define PF_ASSERT_UNLOCKED() do { \
- if (rw_status(&pf_lock) == RW_WRITE) \
- splassert_fail(0, rw_status(&pf_lock), __func__);\
- } while (0)
+#define PF_ASSERT_UNLOCKED() (void)(0)
#define PF_STATE_ENTER_READ() do { \
- rw_enter_read(&pf_state_lock); \
+ mtx_enter(&pf_state_lock); \
} while (0)
#define PF_STATE_EXIT_READ() do { \
- rw_exit_read(&pf_state_lock); \
+ mtx_leave(&pf_state_lock); \
} while (0)
#define PF_STATE_ENTER_WRITE() do { \
- rw_enter_write(&pf_state_lock); \
+ mtx_enter(&pf_state_lock); \
} while (0)
#define PF_STATE_EXIT_WRITE() do { \
PF_ASSERT_STATE_LOCKED(); \
- rw_exit_write(&pf_state_lock); \
+ mtx_leave(&pf_state_lock); \
} while (0)
-#define PF_ASSERT_STATE_LOCKED() do { \
- if (rw_status(&pf_state_lock) != RW_WRITE)\
- splassert_fail(RW_WRITE, \
- rw_status(&pf_state_lock), __func__);\
- } while (0)
+#define PF_ASSERT_STATE_LOCKED() (void)(0)
extern void pf_purge_timeout(void *);
extern void pf_purge(void *);