kern/182964: commit references a PR

dfilter service dfilter at FreeBSD.ORG
Tue Feb 18 22:20:02 UTC 2014


The following reply was made to PR kern/182964; it has been noted by GNATS.

From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: kern/182964: commit references a PR
Date: Tue, 18 Feb 2014 22:17:26 +0000 (UTC)

 Author: mm
 Date: Tue Feb 18 22:17:12 2014
 New Revision: 262196
 URL: http://svnweb.freebsd.org/changeset/base/262196
 
 Log:
   De-virtualize pf_mtag_z [1]
   Process V_pf_overloadqueue in vnet context [2]
   
   This fixes two VIMAGE kernel panics and allows to simultaneously run host-pf
   and vnet jails. pf inside jails remains broken.
   
   PR:		kern/182964
   Submitted by:	glebius at FreeBSD.org [2], myself [1]
   Tested by:	rodrigc at FreeBSD.org, myself
   MFC after:	2 weeks
 
 Modified:
   head/sys/netpfil/pf/pf.c
 
 Modified: head/sys/netpfil/pf/pf.c
 ==============================================================================
 --- head/sys/netpfil/pf/pf.c	Tue Feb 18 22:16:24 2014	(r262195)
 +++ head/sys/netpfil/pf/pf.c	Tue Feb 18 22:17:12 2014	(r262196)
 @@ -172,7 +172,10 @@ struct pf_overload_entry {
  	struct pf_rule  		*rule;
  };
  
 -SLIST_HEAD(pf_overload_head, pf_overload_entry);
 +struct pf_overload_head {
 +	SLIST_HEAD(, pf_overload_entry) head;
 +	struct vnet			*vnet;
 +};
  static VNET_DEFINE(struct pf_overload_head, pf_overloadqueue);
  #define V_pf_overloadqueue	VNET(pf_overloadqueue)
  static VNET_DEFINE(struct task, pf_overloadtask);
 @@ -187,8 +190,7 @@ struct mtx pf_unlnkdrules_mtx;
  
  static VNET_DEFINE(uma_zone_t,	pf_sources_z);
  #define	V_pf_sources_z	VNET(pf_sources_z)
 -static VNET_DEFINE(uma_zone_t,	pf_mtag_z);
 -#define	V_pf_mtag_z	VNET(pf_mtag_z)
 +uma_zone_t pf_mtag_z;
  VNET_DEFINE(uma_zone_t,	 pf_state_z);
  VNET_DEFINE(uma_zone_t,	 pf_state_key_z);
  
 @@ -510,7 +512,7 @@ pf_src_connlimit(struct pf_state **state
  	pfoe->rule = (*state)->rule.ptr;
  	pfoe->dir = (*state)->direction;
  	PF_OVERLOADQ_LOCK();
 -	SLIST_INSERT_HEAD(&V_pf_overloadqueue, pfoe, next);
 +	SLIST_INSERT_HEAD(&V_pf_overloadqueue.head, pfoe, next);
  	PF_OVERLOADQ_UNLOCK();
  	taskqueue_enqueue(taskqueue_swi, &V_pf_overloadtask);
  
 @@ -527,11 +529,13 @@ pf_overload_task(void *c, int pending)
  
  	PF_OVERLOADQ_LOCK();
  	queue = *(struct pf_overload_head *)c;
 -	SLIST_INIT((struct pf_overload_head *)c);
 +	SLIST_INIT(&((struct pf_overload_head *)c)->head);
  	PF_OVERLOADQ_UNLOCK();
  
 +	CURVNET_SET(queue.vnet);
 +
  	bzero(&p, sizeof(p));
 -	SLIST_FOREACH(pfoe, &queue, next) {
 +	SLIST_FOREACH(pfoe, &queue.head, next) {
  		V_pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
  		if (V_pf_status.debug >= PF_DEBUG_MISC) {
  			printf("%s: blocking address ", __func__);
 @@ -563,16 +567,18 @@ pf_overload_task(void *c, int pending)
  	/*
  	 * Remove those entries, that don't need flushing.
  	 */
 -	SLIST_FOREACH_SAFE(pfoe, &queue, next, pfoe1)
 +	SLIST_FOREACH_SAFE(pfoe, &queue.head, next, pfoe1)
  		if (pfoe->rule->flush == 0) {
 -			SLIST_REMOVE(&queue, pfoe, pf_overload_entry, next);
 +			SLIST_REMOVE(&queue.head, pfoe, pf_overload_entry, next);
  			free(pfoe, M_PFTEMP);
  		} else
  			V_pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
  
  	/* If nothing to flush, return. */
 -	if (SLIST_EMPTY(&queue))
 +	if (SLIST_EMPTY(&queue.head)) {
 +		CURVNET_RESTORE();
  		return;
 +	}
  
  	for (int i = 0; i <= V_pf_hashmask; i++) {
  		struct pf_idhash *ih = &V_pf_idhash[i];
 @@ -582,7 +588,7 @@ pf_overload_task(void *c, int pending)
  		PF_HASHROW_LOCK(ih);
  		LIST_FOREACH(s, &ih->states, entry) {
  		    sk = s->key[PF_SK_WIRE];
 -		    SLIST_FOREACH(pfoe, &queue, next)
 +		    SLIST_FOREACH(pfoe, &queue.head, next)
  			if (sk->af == pfoe->af &&
  			    ((pfoe->rule->flush & PF_FLUSH_GLOBAL) ||
  			    pfoe->rule == s->rule.ptr) &&
 @@ -597,10 +603,12 @@ pf_overload_task(void *c, int pending)
  		}
  		PF_HASHROW_UNLOCK(ih);
  	}
 -	SLIST_FOREACH_SAFE(pfoe, &queue, next, pfoe1)
 +	SLIST_FOREACH_SAFE(pfoe, &queue.head, next, pfoe1)
  		free(pfoe, M_PFTEMP);
  	if (V_pf_status.debug >= PF_DEBUG_MISC)
  		printf("%s: %u states killed", __func__, killed);
 +
 +	CURVNET_RESTORE();
  }
  
  /*
 @@ -790,14 +798,16 @@ pf_initialize()
  	V_pf_altqs_inactive = &V_pf_altqs[1];
  
  	/* Mbuf tags */
 -	V_pf_mtag_z = uma_zcreate("pf mtags", sizeof(struct m_tag) +
 -	    sizeof(struct pf_mtag), NULL, NULL, pf_mtag_init, NULL,
 -	    UMA_ALIGN_PTR, 0);
 +	if (IS_DEFAULT_VNET(curvnet))
 +		pf_mtag_z = uma_zcreate("pf mtags", sizeof(struct m_tag) +
 +		    sizeof(struct pf_mtag), NULL, NULL, pf_mtag_init, NULL,
 +		    UMA_ALIGN_PTR, 0);
  
  	/* Send & overload+flush queues. */
  	STAILQ_INIT(&V_pf_sendqueue);
 -	SLIST_INIT(&V_pf_overloadqueue);
 +	SLIST_INIT(&V_pf_overloadqueue.head);
  	TASK_INIT(&V_pf_overloadtask, 0, pf_overload_task, &V_pf_overloadqueue);
 +	V_pf_overloadqueue.vnet = curvnet;
  	mtx_init(&pf_sendqueue_mtx, "pf send queue", NULL, MTX_DEF);
  	mtx_init(&pf_overloadqueue_mtx, "pf overload/flush queue", NULL,
  	    MTX_DEF);
 @@ -844,7 +854,8 @@ pf_cleanup()
  	mtx_destroy(&pf_overloadqueue_mtx);
  	mtx_destroy(&pf_unlnkdrules_mtx);
  
 -	uma_zdestroy(V_pf_mtag_z);
 +	if (IS_DEFAULT_VNET(curvnet))
 +		uma_zdestroy(pf_mtag_z);
  	uma_zdestroy(V_pf_sources_z);
  	uma_zdestroy(V_pf_state_z);
  	uma_zdestroy(V_pf_state_key_z);
 @@ -868,7 +879,7 @@ static void
  pf_mtag_free(struct m_tag *t)
  {
  
 -	uma_zfree(V_pf_mtag_z, t);
 +	uma_zfree(pf_mtag_z, t);
  }
  
  struct pf_mtag *
 @@ -879,7 +890,7 @@ pf_get_mtag(struct mbuf *m)
  	if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) != NULL)
  		return ((struct pf_mtag *)(mtag + 1));
  
 -	mtag = uma_zalloc(V_pf_mtag_z, M_NOWAIT);
 +	mtag = uma_zalloc(pf_mtag_z, M_NOWAIT);
  	if (mtag == NULL)
  		return (NULL);
  	bzero(mtag + 1, sizeof(struct pf_mtag));
 @@ -1675,7 +1686,7 @@ pf_purge_unlinked_rules()
  	 * an already unlinked rule.
  	 */
  	PF_OVERLOADQ_LOCK();
 -	if (!SLIST_EMPTY(&V_pf_overloadqueue)) {
 +	if (!SLIST_EMPTY(&V_pf_overloadqueue.head)) {
  		PF_OVERLOADQ_UNLOCK();
  		return;
  	}
 _______________________________________________
 svn-src-all at freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
 


More information about the freebsd-bugs mailing list