Hello,

> Hrvoje Popovski confirmed this reduces "ifconfig" pauses.  He also
> confirmed states are correctly purged.
> 
> So, I'd appreciate reviews and oks.

sorry for keeping you waiting. the change looks good. just a small nit, which I
don't insist on.

> > Index: net/pfvar.h
> > ===================================================================
> > RCS file: /cvs/src/sys/net/pfvar.h,v
> > retrieving revision 1.460
> > diff -u -p -r1.460 pfvar.h
> > --- net/pfvar.h     28 Jun 2017 19:30:24 -0000      1.460
> > +++ net/pfvar.h     18 Jul 2017 13:30:23 -0000
> > @@ -1647,7 +1647,8 @@ extern int                     
> > pf_tbladdr_setup(struct pf
> >  extern void                         pf_tbladdr_remove(struct pf_addr_wrap 
> > *);
> >  extern void                         pf_tbladdr_copyout(struct pf_addr_wrap 
> > *);
> >  extern void                         pf_calc_skip_steps(struct pf_rulequeue 
> > *);
> > -extern void                         pf_purge_thread(void *);
> > +extern void                         pf_purge_timeout(void *);
> > +extern void                         pf_purge(void *);
> >  extern void                         pf_purge_expired_src_nodes();
> >  extern void                         pf_purge_expired_states(u_int32_t);
> >  extern void                         pf_purge_expired_rules();
> > @@ -1826,6 +1827,8 @@ const struct pfq_ops
> >             *pf_queue_manager(struct pf_queuespec *);
> >  
> >  extern struct pf_status    pf_status;
> > +extern struct task pf_purge_task;
> > +extern struct timeout      pf_purge_to;
> >  extern struct pool pf_frent_pl, pf_frag_pl;
> >  

    I think those declarations should go to net/pfvar_priv.h, which has been
    introduced sometime ago. The idea is to split current net/pfvar.h to
    two header files:
        public (net/pfvar.h)
        and private to be included by PF source code only (net/pfvar_priv.h)

I've just updated your patch with change I'm suggesting.

thanks and
regards
sasha

and of course O.K. sashan@

--------8<---------------8<---------------8<------------------8<--------
diff -r 8a63415bc696 src/sys/net/pf.c
--- src/sys/net/pf.c    Wed Jul 26 08:30:24 2017 +0200
+++ src/sys/net/pf.c    Thu Jul 27 09:00:45 2017 +0200
@@ -121,6 +121,10 @@ u_char                      pf_tcp_secret[16];
 int                     pf_tcp_secret_init;
 int                     pf_tcp_iss_off;
 
+int             pf_npurge;
+struct task     pf_purge_task = TASK_INITIALIZER(pf_purge, &pf_npurge);
+struct timeout  pf_purge_to = TIMEOUT_INITIALIZER(pf_purge_timeout, NULL);
+
 enum pf_test_status {
        PF_TEST_FAIL = -1,
        PF_TEST_OK,
@@ -1200,36 +1204,44 @@ pf_purge_expired_rules(void)
 }
 
 void
-pf_purge_thread(void *v)
+pf_purge_timeout(void *unused)
+{
+       task_add(softnettq, &pf_purge_task);
+}
+
+void
+pf_purge(void *xnloops)
 {
-       int nloops = 0, s;
-
-       for (;;) {
-               tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
-
-               NET_LOCK(s);
-
-               PF_LOCK();
-               /* process a fraction of the state table every second */
-               pf_purge_expired_states(1 + (pf_status.states
-                   / pf_default_rule.timeout[PFTM_INTERVAL]));
-
-               /* purge other expired types every PFTM_INTERVAL seconds */
-               if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
-                       pf_purge_expired_src_nodes(0);
-                       pf_purge_expired_rules();
-               }
-               PF_UNLOCK();
-               /*
-                * Fragments don't require PF_LOCK(), they use their own lock.
-                */
-               if (nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
-                       pf_purge_expired_fragments();
-                       nloops = 0;
-               }
-
-               NET_UNLOCK(s);
-       }
+       int *nloops = xnloops;
+       int s;
+
+       KERNEL_LOCK();
+       NET_LOCK(s);
+
+       PF_LOCK();
+       /* process a fraction of the state table every second */
+       pf_purge_expired_states(1 + (pf_status.states
+           / pf_default_rule.timeout[PFTM_INTERVAL]));
+
+       /* purge other expired types every PFTM_INTERVAL seconds */
+       if (++(*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) {
+               pf_purge_expired_src_nodes(0);
+               pf_purge_expired_rules();
+       }
+       PF_UNLOCK();
+
+       /*
+        * Fragments don't require PF_LOCK(), they use their own lock.
+        */
+       if ((*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) {
+               pf_purge_expired_fragments();
+               *nloops = 0;
+       }
+       NET_UNLOCK(s);
+       KERNEL_UNLOCK();
+
+       if (pf_status.running)
+               timeout_add(&pf_purge_to, 1 * hz);
 }
 
 int32_t
diff -r 8a63415bc696 src/sys/net/pf_ioctl.c
--- src/sys/net/pf_ioctl.c      Wed Jul 26 08:30:24 2017 +0200
+++ src/sys/net/pf_ioctl.c      Thu Jul 27 09:00:45 2017 +0200
@@ -231,16 +231,6 @@ pfattach(int num)
 
        /* XXX do our best to avoid a conflict */
        pf_status.hostid = arc4random();
-
-       /* require process context to purge states, so perform in a thread */
-       kthread_create_deferred(pf_thread_create, NULL);
-}
-
-void
-pf_thread_create(void *v)
-{
-       if (kthread_create(pf_purge_thread, NULL, NULL, "pfpurge"))
-               panic("pfpurge thread");
 }
 
 int
@@ -1027,6 +1017,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                                pf_status.stateid = time_second;
                                pf_status.stateid = pf_status.stateid << 32;
                        }
+                       timeout_add(&pf_purge_to, 1 * hz);
                        pf_create_queues();
                        DPFPRINTF(LOG_NOTICE, "pf: started");
                }
@@ -2292,7 +2283,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                            pf_default_rule_new.timeout[i];
                        if (pf_default_rule.timeout[i] == PFTM_INTERVAL &&
                            pf_default_rule.timeout[i] < old)
-                               wakeup(pf_purge_thread);
+                               task_add(softnettq, &pf_purge_task);
                }
                pfi_xcommit();
                pf_trans_set_commit();
diff -r 8a63415bc696 src/sys/net/pfvar.h
--- src/sys/net/pfvar.h Wed Jul 26 08:30:24 2017 +0200
+++ src/sys/net/pfvar.h Thu Jul 27 09:00:45 2017 +0200
@@ -1648,7 +1648,6 @@ extern int                         
pf_tbladdr_setup(struct pf
 extern void                     pf_tbladdr_remove(struct pf_addr_wrap *);
 extern void                     pf_tbladdr_copyout(struct pf_addr_wrap *);
 extern void                     pf_calc_skip_steps(struct pf_rulequeue *);
-extern void                     pf_purge_thread(void *);
 extern void                     pf_purge_expired_src_nodes();
 extern void                     pf_purge_expired_states(u_int32_t);
 extern void                     pf_purge_expired_rules();
diff -r 8a63415bc696 src/sys/net/pfvar_priv.h
--- src/sys/net/pfvar_priv.h    Wed Jul 26 08:30:24 2017 +0200
+++ src/sys/net/pfvar_priv.h    Thu Jul 27 09:00:45 2017 +0200
@@ -98,6 +98,9 @@ struct pf_pdesc {
        } hdr;
 };
 
+extern struct task     pf_purge_task;
+extern struct timeout  pf_purge_to;
+
 #ifdef WITH_PF_LOCK
 extern struct rwlock   pf_lock;
 
@@ -128,6 +131,8 @@ extern struct rwlock        pf_lock;
 #define PF_ASSERT_UNLOCKED()   (void)(0)
 #endif /* WITH_PF_LOCK */
 
+extern void                     pf_purge_timeout(void *);
+extern void                     pf_purge(void *);
 #endif /* _KERNEL */
 
 #endif /* _NET_PFVAR_PRIV_H_ */
--------8<---------------8<---------------8<------------------8<--------

Reply via email to