Author: cy
Date: Thu Jan 26 01:24:05 2017
New Revision: 312787
URL: https://svnweb.freebsd.org/changeset/base/312787

Log:
  Currently the fragment info is placed at the top of the linked list
  under a shared read lock. This patch attempts to upgrade the lock to
  an exclusive write lock. If the exclusive write lock fails to be
  obtained, the current fragment is not placed at the head of the list.
  
  This portion of the patch was inspired by NetBSD ip_frag.c r1.4 (which
  effectively removed the section of code that performed the reordering).
  
  The patch to sys/contrib/ipfilter/netinet/ip_compat.h adds the
  MUTEX_TRY_UPGRADE macro to support the patch to ip_frag.c.
  
  The patch to contrib/ipfilter/lib/rwlock_emul.c supports this patch
  by emulating the mutex in userspace when exercised by ipftest(1).
  
  Inspired by:  NetBSD ip_frag.c r1.4
  MFC after:    1 month

Modified:
  head/contrib/ipfilter/lib/rwlock_emul.c
  head/sys/contrib/ipfilter/netinet/ip_compat.h
  head/sys/contrib/ipfilter/netinet/ip_frag.c

Modified: head/contrib/ipfilter/lib/rwlock_emul.c
==============================================================================
--- head/contrib/ipfilter/lib/rwlock_emul.c     Wed Jan 25 23:12:03 2017        
(r312786)
+++ head/contrib/ipfilter/lib/rwlock_emul.c     Thu Jan 26 01:24:05 2017        
(r312787)
@@ -56,6 +56,27 @@ void eMrwlock_write_enter(rw, file, line
 }
 
 
+void eMrwlock_try_upgrade(rw, file, line)
+       eMrwlock_t *rw;
+       char *file;
+       int line;
+{
+       if (rw->eMrw_magic != EMM_MAGIC) {
+               fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
+                       rw->eMrw_owner, rw, rw->eMrw_magic);
+               abort();
+       }
+       if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
+               fprintf(stderr,
+                       "%s:eMrwlock_try_upgrade(%p): already locked: %d/%d\n",
+                       rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
+               abort();
+       }
+       rw->eMrw_write++;
+       rw->eMrw_heldin = file;
+       rw->eMrw_heldat = line;
+}
+
 void eMrwlock_downgrade(rw, file, line)
        eMrwlock_t *rw;
        char *file;

Modified: head/sys/contrib/ipfilter/netinet/ip_compat.h
==============================================================================
--- head/sys/contrib/ipfilter/netinet/ip_compat.h       Wed Jan 25 23:12:03 
2017        (r312786)
+++ head/sys/contrib/ipfilter/netinet/ip_compat.h       Thu Jan 26 01:24:05 
2017        (r312787)
@@ -165,6 +165,7 @@ struct  ether_addr {
 #    define    READ_ENTER(x)           rw_rlock(&(x)->ipf_lk)
 #    define    WRITE_ENTER(x)          rw_wlock(&(x)->ipf_lk)
 #    define    MUTEX_DOWNGRADE(x)      rw_downgrade(&(x)->ipf_lk)
+#    define    MUTEX_TRY_UPGRADE(x)    rw_try_upgrade(&(x)->ipf_lk)
 #    define    RWLOCK_INIT(x,y)        rw_init(&(x)->ipf_lk, (y))
 #    define    RW_DESTROY(x)           rw_destroy(&(x)->ipf_lk)
 #    define    RWLOCK_EXIT(x)          do { \
@@ -421,6 +422,8 @@ extern      void    freembt __P((mb_t *));
 
 # define       MUTEX_DOWNGRADE(x)      eMrwlock_downgrade(&(x)->ipf_emu, \
                                                           __FILE__, __LINE__)
+# define       MUTEX_TRY_UPGRADE(x)    eMrwlock_try_upgrade(&(x)->ipf_emu, \
+                                                          __FILE__, __LINE__)
 # define       READ_ENTER(x)           eMrwlock_read_enter(&(x)->ipf_emu, \
                                                            __FILE__, __LINE__)
 # define       RWLOCK_INIT(x, y)       eMrwlock_init(&(x)->ipf_emu, y)
@@ -671,6 +674,7 @@ extern      char    *ipf_getifname __P((struct i
 # define       READ_ENTER(x)           ;
 # define       WRITE_ENTER(x)          ;
 # define       MUTEX_DOWNGRADE(x)      ;
+# define       MUTEX_TRY_UPGRADE(x)    ;
 # define       RWLOCK_INIT(x, y)       ;
 # define       RWLOCK_EXIT(x)          ;
 # define       RW_DESTROY(x)           ;

Modified: head/sys/contrib/ipfilter/netinet/ip_frag.c
==============================================================================
--- head/sys/contrib/ipfilter/netinet/ip_frag.c Wed Jan 25 23:12:03 2017        
(r312786)
+++ head/sys/contrib/ipfilter/netinet/ip_frag.c Thu Jan 26 01:24:05 2017        
(r312787)
@@ -745,7 +745,7 @@ ipf_frag_lookup(softc, softf, fin, table
                        } else if (off == 0)
                                f->ipfr_seen0 = 1;
 
-                       if (f != table[idx]) {
+                       if (f != table[idx] && MUTEX_TRY_UPGRADE(lock)) {
                                ipfr_t **fp;
 
                                /*
@@ -763,6 +763,7 @@ ipf_frag_lookup(softc, softf, fin, table
                                table[idx]->ipfr_hprev = &f->ipfr_hnext;
                                f->ipfr_hprev = table + idx;
                                table[idx] = f;
+                               MUTEX_DOWNGRADE(lock);
                        }
 
                        /*
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to