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 *);

Reply via email to