Date: Sun, 3 Jun 2012 20:07:38 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r236526 - projects/pf/head/sys/contrib/pf/net Message-ID: <201206032007.q53K7cok081952@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Sun Jun 3 20:07:37 2012 New Revision: 236526 URL: http://svn.freebsd.org/changeset/base/236526 Log: pfsync_sendout() is usually called when softc has accumulated enough data to send a packet, and now is being requested to add data that would overflow a packet. Thus, swi scheduled at the end of pfsync_sendout() is going to service not a single packet, but a couple of them, and the second one is containg only one piece of pfsync data. This leads to coupling of pfsync pps: every odd packet is full-sized and every even is undersized. To fix this, a flag is added to softc - PFSYNCF_PUSH, which indicates, whether we swi handler needs to sqeeze data from the softc prior to sending packets. In all cases when we need to send data immidiately, this flags is raised prioir to swi_sched(). But in case of usual sc_len overflow, it isn't raised. Modified: projects/pf/head/sys/contrib/pf/net/if_pfsync.c Modified: projects/pf/head/sys/contrib/pf/net/if_pfsync.c ============================================================================== --- projects/pf/head/sys/contrib/pf/net/if_pfsync.c Sun Jun 3 19:25:48 2012 (r236525) +++ projects/pf/head/sys/contrib/pf/net/if_pfsync.c Sun Jun 3 20:07:37 2012 (r236526) @@ -203,6 +203,7 @@ struct pfsync_softc { uint32_t sc_flags; #define PFSYNCF_OK 0x00000001 #define PFSYNCF_DEFER 0x00000002 +#define PFSYNCF_PUSH 0x00000004 uint8_t sc_maxupdates; struct ip sc_template; struct callout sc_tmo; @@ -248,6 +249,7 @@ static VNET_DEFINE(int, pfsync_carp_adj) #define V_pfsync_carp_adj VNET(pfsync_carp_adj) static void pfsync_timeout(void *); +static void pfsync_push(struct pfsync_softc *); static void pfsyncintr(void *); static int pfsync_multicast_setup(struct pfsync_softc *, struct ifnet *, void *); @@ -417,6 +419,7 @@ pfsync_alloc_scrub_memory(struct pfsync_ static int pfsync_state_import(struct pfsync_state *sp, u_int8_t flags) { + struct pfsync_softc *sc = V_pfsyncif; struct pf_state *st = NULL; struct pf_state_key *skw = NULL, *sks = NULL; struct pf_rule *r = NULL; @@ -546,7 +549,7 @@ pfsync_state_import(struct pfsync_state st->state_flags &= ~PFSTATE_NOSYNC; if (st->state_flags & PFSTATE_ACK) { pfsync_q_ins(st, PFSYNC_S_IACK); - swi_sched(V_pfsync_swi_cookie, 0); + pfsync_push(sc); } } st->state_flags &= ~PFSTATE_ACK; @@ -826,6 +829,7 @@ pfsync_upd_tcp(struct pf_state *st, stru static int pfsync_in_upd(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) { + struct pfsync_softc *sc = V_pfsyncif; struct pfsync_state *sa, *sp; struct pf_state_key *sk; struct pf_state *st; @@ -866,9 +870,9 @@ pfsync_in_upd(struct pfsync_pkt *pkt, st } if (st->state_flags & PFSTATE_ACK) { - PFSYNC_LOCK(V_pfsyncif); + PFSYNC_LOCK(sc); pfsync_undefer_state(st, 1); - PFSYNC_UNLOCK(V_pfsyncif); + PFSYNC_UNLOCK(sc); } sk = st->key[PF_SK_WIRE]; /* XXX right one? */ @@ -898,7 +902,9 @@ pfsync_in_upd(struct pfsync_pkt *pkt, st pfsync_update_state(st); PF_STATE_UNLOCK(st); - swi_sched(V_pfsync_swi_cookie, 0); + PFSYNC_LOCK(sc); + pfsync_push(sc); + PFSYNC_UNLOCK(sc); continue; } pfsync_alloc_scrub_memory(&sp->dst, &st->dst); @@ -916,6 +922,7 @@ pfsync_in_upd(struct pfsync_pkt *pkt, st static int pfsync_in_upd_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count) { + struct pfsync_softc *sc = V_pfsyncif; struct pfsync_upd_c *ua, *up; struct pf_state_key *sk; struct pf_state *st; @@ -952,16 +959,16 @@ pfsync_in_upd_c(struct pfsync_pkt *pkt, st = pf_find_state_byid(up->id, up->creatorid); if (st == NULL) { /* We don't have this state. Ask for it. */ - PFSYNC_LOCK(V_pfsyncif); + PFSYNC_LOCK(sc); pfsync_request_update(up->creatorid, up->id); - PFSYNC_UNLOCK(V_pfsyncif); + PFSYNC_UNLOCK(sc); continue; } if (st->state_flags & PFSTATE_ACK) { - PFSYNC_LOCK(V_pfsyncif); + PFSYNC_LOCK(sc); pfsync_undefer_state(st, 1); - PFSYNC_UNLOCK(V_pfsyncif); + PFSYNC_UNLOCK(sc); } sk = st->key[PF_SK_WIRE]; /* XXX right one? */ @@ -990,7 +997,9 @@ pfsync_in_upd_c(struct pfsync_pkt *pkt, pfsync_update_state(st); PF_STATE_UNLOCK(st); - swi_sched(V_pfsync_swi_cookie, 0); + PFSYNC_LOCK(sc); + pfsync_push(sc); + PFSYNC_UNLOCK(sc); continue; } pfsync_alloc_scrub_memory(&up->dst, &st->dst); @@ -1712,7 +1721,7 @@ pfsync_defer(struct pf_state *st, struct callout_init_mtx(&pd->pd_tmo, &sc->sc_mtx, CALLOUT_RETURNUNLOCKED); callout_reset(&pd->pd_tmo, 10, pfsync_defer_tmo, pd); - swi_sched(V_pfsync_swi_cookie, 0); + pfsync_push(sc); return (1); } @@ -1736,7 +1745,7 @@ pfsync_undefer(struct pfsync_deferral *p m_freem(m); else { _IF_ENQUEUE(&sc->sc_ifp->if_snd, m); - swi_sched(V_pfsync_swi_cookie, 0); + pfsync_push(sc); } } @@ -1829,10 +1838,11 @@ pfsync_update_state(struct pf_state *st) default: panic("%s: unexpected sync state %d", __func__, st->sync_state); } - PFSYNC_UNLOCK(sc); if (sync || (time_uptime - st->pfsync_time) < 2) - swi_sched(V_pfsync_swi_cookie, 0); + pfsync_push(sc); + + PFSYNC_UNLOCK(sc); } static void @@ -1868,7 +1878,7 @@ pfsync_request_update(u_int32_t creatori TAILQ_INSERT_TAIL(&sc->sc_upd_req_list, item, ur_entry); sc->sc_len += nlen; - swi_sched(V_pfsync_swi_cookie, 0); + pfsync_push(sc); } static void @@ -1892,7 +1902,7 @@ pfsync_update_state_req(struct pf_state pfsync_q_del(st); case PFSYNC_S_NONE: pfsync_q_ins(st, PFSYNC_S_UPD); - swi_sched(V_pfsync_swi_cookie, 0); + pfsync_push(sc); break; case PFSYNC_S_INS: @@ -2178,16 +2188,23 @@ pfsync_send_plus(void *plus, size_t plus static void pfsync_timeout(void *arg) { -#ifdef VIMAGE struct pfsync_softc *sc = arg; -#endif CURVNET_SET(sc->sc_ifp->if_vnet); - swi_sched(V_pfsync_swi_cookie, 0); + pfsync_push(sc); CURVNET_RESTORE(); } -/* this is a softnet/netisr handler */ +static void +pfsync_push(struct pfsync_softc *sc) +{ + + PFSYNC_LOCK_ASSERT(sc); + + sc->sc_flags |= PFSYNCF_PUSH; + swi_sched(V_pfsync_swi_cookie, 0); +} + static void pfsyncintr(void *arg) { @@ -2197,8 +2214,10 @@ pfsyncintr(void *arg) CURVNET_SET(sc->sc_ifp->if_vnet); PFSYNC_LOCK(sc); - if (sc->sc_len > PFSYNC_MINPKT) + if ((sc->sc_flags & PFSYNCF_PUSH) && sc->sc_len > PFSYNC_MINPKT) { pfsync_sendout(0); + sc->sc_flags &= ~PFSYNCF_PUSH; + } _IF_DEQUEUE_ALL(&sc->sc_ifp->if_snd, m); PFSYNC_UNLOCK(sc);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206032007.q53K7cok081952>