Date: Thu, 31 Jul 2014 23:04:41 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r269356 - stable/10/sys/dev/cxgbe Message-ID: <201407312304.s6VN4fer066720@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Thu Jul 31 23:04:41 2014 New Revision: 269356 URL: http://svnweb.freebsd.org/changeset/base/269356 Log: MFC r268971 and r269032. r268971: Simplify r267600, there's no need to distinguish between allocated and inlined mbufs. r269032: cxgbe(4): Keep track of the clusters that have to be freed by the custom free routine (rxb_free) in the driver. Fail MOD_UNLOAD with EBUSY if any such cluster has been handed up to the kernel but hasn't been freed yet. This prevents a panic later when the cluster finally needs to be freed but rxb_free is gone from the kernel. Modified: stable/10/sys/dev/cxgbe/adapter.h stable/10/sys/dev/cxgbe/t4_main.c stable/10/sys/dev/cxgbe/t4_sge.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/cxgbe/adapter.h ============================================================================== --- stable/10/sys/dev/cxgbe/adapter.h Thu Jul 31 22:32:39 2014 (r269355) +++ stable/10/sys/dev/cxgbe/adapter.h Thu Jul 31 23:04:41 2014 (r269356) @@ -254,8 +254,7 @@ struct cluster_metadata { struct fl_sdesc { caddr_t cl; - uint8_t nimbuf; /* # of inline mbufs with ref on the cluster */ - uint8_t nembuf; /* # of allocated mbufs with ref */ + uint16_t nmbuf; /* # of driver originated mbufs with ref on cluster */ struct cluster_layout cll; }; @@ -852,6 +851,8 @@ void end_synchronized_op(struct adapter /* t4_sge.c */ void t4_sge_modload(void); +void t4_sge_modunload(void); +uint64_t t4_sge_extfree_refs(void); void t4_init_sge_cpl_handlers(struct adapter *); void t4_tweak_chip_settings(struct adapter *); int t4_read_chip_settings(struct adapter *); Modified: stable/10/sys/dev/cxgbe/t4_main.c ============================================================================== --- stable/10/sys/dev/cxgbe/t4_main.c Thu Jul 31 22:32:39 2014 (r269355) +++ stable/10/sys/dev/cxgbe/t4_main.c Thu Jul 31 23:04:41 2014 (r269356) @@ -8090,6 +8090,9 @@ tweak_tunables(void) t4_intr_types &= INTR_MSIX | INTR_MSI | INTR_INTX; } +static struct sx mlu; /* mod load unload */ +SX_SYSINIT(cxgbe_mlu, &mlu, "cxgbe mod load/unload"); + static int mod_event(module_t mod, int cmd, void *arg) { @@ -8098,41 +8101,67 @@ mod_event(module_t mod, int cmd, void *a switch (cmd) { case MOD_LOAD: - if (atomic_fetchadd_int(&loaded, 1)) - break; - t4_sge_modload(); - sx_init(&t4_list_lock, "T4/T5 adapters"); - SLIST_INIT(&t4_list); + sx_xlock(&mlu); + if (loaded++ == 0) { + t4_sge_modload(); + sx_init(&t4_list_lock, "T4/T5 adapters"); + SLIST_INIT(&t4_list); #ifdef TCP_OFFLOAD - sx_init(&t4_uld_list_lock, "T4/T5 ULDs"); - SLIST_INIT(&t4_uld_list); + sx_init(&t4_uld_list_lock, "T4/T5 ULDs"); + SLIST_INIT(&t4_uld_list); #endif - t4_tracer_modload(); - tweak_tunables(); + t4_tracer_modload(); + tweak_tunables(); + } + sx_xunlock(&mlu); break; case MOD_UNLOAD: - if (atomic_fetchadd_int(&loaded, -1) > 1) - break; - t4_tracer_modunload(); + sx_xlock(&mlu); + if (--loaded == 0) { + int tries; + + sx_slock(&t4_list_lock); + if (!SLIST_EMPTY(&t4_list)) { + rc = EBUSY; + sx_sunlock(&t4_list_lock); + goto done_unload; + } +#ifdef TCP_OFFLOAD + sx_slock(&t4_uld_list_lock); + if (!SLIST_EMPTY(&t4_uld_list)) { + rc = EBUSY; + sx_sunlock(&t4_uld_list_lock); + sx_sunlock(&t4_list_lock); + goto done_unload; + } +#endif + tries = 0; + while (tries++ < 5 && t4_sge_extfree_refs() != 0) { + uprintf("%ju clusters with custom free routine " + "still is use.\n", t4_sge_extfree_refs()); + pause("t4unload", 2 * hz); + } #ifdef TCP_OFFLOAD - sx_slock(&t4_uld_list_lock); - if (!SLIST_EMPTY(&t4_uld_list)) { - rc = EBUSY; sx_sunlock(&t4_uld_list_lock); - break; - } - sx_sunlock(&t4_uld_list_lock); - sx_destroy(&t4_uld_list_lock); #endif - sx_slock(&t4_list_lock); - if (!SLIST_EMPTY(&t4_list)) { - rc = EBUSY; sx_sunlock(&t4_list_lock); - break; + + if (t4_sge_extfree_refs() == 0) { + t4_tracer_modunload(); +#ifdef TCP_OFFLOAD + sx_destroy(&t4_uld_list_lock); +#endif + sx_destroy(&t4_list_lock); + t4_sge_modunload(); + loaded = 0; + } else { + rc = EBUSY; + loaded++; /* undo earlier decrement */ + } } - sx_sunlock(&t4_list_lock); - sx_destroy(&t4_list_lock); +done_unload: + sx_xunlock(&mlu); break; } Modified: stable/10/sys/dev/cxgbe/t4_sge.c ============================================================================== --- stable/10/sys/dev/cxgbe/t4_sge.c Thu Jul 31 22:32:39 2014 (r269355) +++ stable/10/sys/dev/cxgbe/t4_sge.c Thu Jul 31 23:04:41 2014 (r269356) @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <sys/time.h> #include <sys/sysctl.h> #include <sys/smp.h> +#include <sys/counter.h> #include <net/bpf.h> #include <net/ethernet.h> #include <net/if.h> @@ -242,6 +243,9 @@ static int handle_fw_msg(struct sge_iq * static int sysctl_uint16(SYSCTL_HANDLER_ARGS); static int sysctl_bufsizes(SYSCTL_HANDLER_ARGS); +static counter_u64_t extfree_refs; +static counter_u64_t extfree_rels; + /* * Called on MOD_LOAD. Validates and calculates the SGE tunables. */ @@ -313,6 +317,30 @@ t4_sge_modload(void) " using 0 instead.\n", cong_drop); cong_drop = 0; } + + extfree_refs = counter_u64_alloc(M_WAITOK); + extfree_rels = counter_u64_alloc(M_WAITOK); + counter_u64_zero(extfree_refs); + counter_u64_zero(extfree_rels); +} + +void +t4_sge_modunload(void) +{ + + counter_u64_free(extfree_refs); + counter_u64_free(extfree_rels); +} + +uint64_t +t4_sge_extfree_refs(void) +{ + uint64_t refs, rels; + + rels = counter_u64_fetch(extfree_rels); + refs = counter_u64_fetch(extfree_refs); + + return (refs - rels); } void @@ -1450,6 +1478,7 @@ rxb_free(struct mbuf *m, void *arg1, voi caddr_t cl = arg2; uma_zfree(zone, cl); + counter_u64_add(extfree_rels, 1); return (EXT_FREE_OK); } @@ -1498,7 +1527,7 @@ get_scatter_segment(struct adapter *sc, /* copy data to mbuf */ bcopy(payload, mtod(m, caddr_t), len); - } else if (sd->nimbuf * MSIZE < cll->region1) { + } else if (sd->nmbuf * MSIZE < cll->region1) { /* * There's spare room in the cluster for an mbuf. Create one @@ -1506,14 +1535,15 @@ get_scatter_segment(struct adapter *sc, */ MPASS(clm != NULL); - m = (struct mbuf *)(sd->cl + sd->nimbuf * MSIZE); + m = (struct mbuf *)(sd->cl + sd->nmbuf * MSIZE); /* No bzero required */ if (m_init(m, NULL, 0, M_NOWAIT, MT_DATA, flags | M_NOFREE)) return (NULL); fl->mbuf_inlined++; m_extaddref(m, payload, padded_len, &clm->refcount, rxb_free, swz->zone, sd->cl); - sd->nimbuf++; + if (sd->nmbuf++ == 0) + counter_u64_add(extfree_refs, 1); } else { @@ -1530,7 +1560,8 @@ get_scatter_segment(struct adapter *sc, if (clm != NULL) { m_extaddref(m, payload, padded_len, &clm->refcount, rxb_free, swz->zone, sd->cl); - sd->nembuf++; + if (sd->nmbuf++ == 0) + counter_u64_add(extfree_refs, 1); } else { m_cljset(m, sd->cl, swz->type); sd->cl = NULL; /* consumed, not a recycle candidate */ @@ -3055,7 +3086,7 @@ refill_fl(struct adapter *sc, struct sge if (sd->cl != NULL) { - if (sd->nimbuf + sd->nembuf == 0) { + if (sd->nmbuf == 0) { /* * Fast recycle without involving any atomics on * the cluster's metadata (if the cluster has @@ -3082,6 +3113,7 @@ refill_fl(struct adapter *sc, struct sge if (atomic_fetchadd_int(&clm->refcount, -1) == 1) { fl->cl_recycled++; + counter_u64_add(extfree_rels, 1); goto recycled; } sd->cl = NULL; /* gave up my reference */ @@ -3114,8 +3146,7 @@ recycled: #endif clm->refcount = 1; } - sd->nimbuf = 0; - sd->nembuf = 0; + sd->nmbuf = 0; recycled_fast: fl->pending++; fl->needed--; @@ -3184,9 +3215,11 @@ free_fl_sdesc(struct adapter *sc, struct cll = &sd->cll; clm = cl_metadata(sc, fl, cll, sd->cl); - if (sd->nimbuf + sd->nembuf == 0 || - (clm && atomic_fetchadd_int(&clm->refcount, -1) == 1)) { + if (sd->nmbuf == 0) + uma_zfree(sc->sge.sw_zone_info[cll->zidx].zone, sd->cl); + else if (clm && atomic_fetchadd_int(&clm->refcount, -1) == 1) { uma_zfree(sc->sge.sw_zone_info[cll->zidx].zone, sd->cl); + counter_u64_add(extfree_rels, 1); } sd->cl = NULL; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201407312304.s6VN4fer066720>