Do not acquire IPFW_WLOCK when a named object is created and destroyed.

Acquiring of IPFW_WLOCK is requried for cases when we are going to
change some data that can be accessed during processing of packets flow.
When we create new named object, there are not yet any rules, that
references it, thus holding IPFW_UH_WLOCK is enough to safely update
needed structures. When we destroy an object, we do this only when its
reference counter becomes zero. And it is safe to not acquire IPFW_WLOCK,
because noone references it. The another case is when we failed to finish
some action and thus we are doing rollback and destroying an object, in
this case it is still not referenced by rules and no need to acquire
IPFW_WLOCK.

This also fixes panic with INVARIANTS due to recursive IPFW_WLOCK acquiring.

MFC after:	1 week
Sponsored by:	Yandex LLC
This commit is contained in:
Andrey V. Elsukov 2017-09-20 22:00:06 +00:00
parent 5fff95cc1d
commit 369bc48dc5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=323836
5 changed files with 0 additions and 24 deletions

View File

@ -418,9 +418,7 @@ dyn_create(struct ip_fw_chain *ch, struct tid_info *ti,
return (ENOSPC);
}
ipfw_objhash_add(ni, &obj->no);
IPFW_WLOCK(ch);
SRV_OBJECT(ch, obj->no.kidx) = obj;
IPFW_WUNLOCK(ch);
obj->no.refcnt++;
*pkidx = obj->no.kidx;
IPFW_UH_WUNLOCK(ch);
@ -440,10 +438,8 @@ dyn_destroy(struct ip_fw_chain *ch, struct named_object *no)
no->name, no->etlv, no->kidx, no->refcnt));
DYN_DEBUG("kidx %d", no->kidx);
IPFW_WLOCK(ch);
obj = SRV_OBJECT(ch, no->kidx);
SRV_OBJECT(ch, no->kidx) = NULL;
IPFW_WUNLOCK(ch);
ipfw_objhash_del(CHAIN_TO_SRV(ch), no);
ipfw_objhash_free_idx(CHAIN_TO_SRV(ch), no->kidx);

View File

@ -1925,9 +1925,7 @@ create_table_internal(struct ip_fw_chain *ch, struct tid_info *ti,
tc->no.kidx = kidx;
tc->no.etlv = IPFW_TLV_TBL_NAME;
IPFW_WLOCK(ch);
link_table(ch, tc);
IPFW_WUNLOCK(ch);
}
if (compat != 0)
@ -3229,7 +3227,6 @@ link_table(struct ip_fw_chain *ch, struct table_config *tc)
uint16_t kidx;
IPFW_UH_WLOCK_ASSERT(ch);
IPFW_WLOCK_ASSERT(ch);
ni = CHAIN_TO_NI(ch);
kidx = tc->no.kidx;

View File

@ -208,10 +208,7 @@ nat64lsn_create(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
ipfw_objhash_add(CHAIN_TO_SRV(ch), &cfg->no);
/* Okay, let's link data */
IPFW_WLOCK(ch);
SRV_OBJECT(ch, cfg->no.kidx) = cfg;
IPFW_WUNLOCK(ch);
nat64lsn_start_instance(cfg);
IPFW_UH_WUNLOCK(ch);
@ -259,10 +256,7 @@ nat64lsn_destroy(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
return (EBUSY);
}
IPFW_WLOCK(ch);
SRV_OBJECT(ch, cfg->no.kidx) = NULL;
IPFW_WUNLOCK(ch);
nat64lsn_detach_config(ch, cfg);
IPFW_UH_WUNLOCK(ch);

View File

@ -220,10 +220,7 @@ nat64stl_create(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
error = nat64stl_create_internal(ch, cfg, uc);
if (error == 0) {
/* Okay, let's link data */
IPFW_WLOCK(ch);
SRV_OBJECT(ch, cfg->no.kidx) = cfg;
IPFW_WUNLOCK(ch);
IPFW_UH_WUNLOCK(ch);
return (0);
}
@ -342,10 +339,7 @@ nat64stl_destroy(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
return (EBUSY);
}
IPFW_WLOCK(ch);
SRV_OBJECT(ch, cfg->no.kidx) = NULL;
IPFW_WUNLOCK(ch);
nat64stl_detach_config(ch, cfg);
IPFW_UH_WUNLOCK(ch);

View File

@ -560,9 +560,7 @@ nptv6_create(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
return (ENOSPC);
}
ipfw_objhash_add(ni, &cfg->no);
IPFW_WLOCK(ch);
SRV_OBJECT(ch, cfg->no.kidx) = cfg;
IPFW_WUNLOCK(ch);
IPFW_UH_WUNLOCK(ch);
return (0);
}
@ -599,10 +597,7 @@ nptv6_destroy(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
return (EBUSY);
}
IPFW_WLOCK(ch);
SRV_OBJECT(ch, cfg->no.kidx) = NULL;
IPFW_WUNLOCK(ch);
ipfw_objhash_del(CHAIN_TO_SRV(ch), &cfg->no);
ipfw_objhash_free_idx(CHAIN_TO_SRV(ch), cfg->no.kidx);
IPFW_UH_WUNLOCK(ch);