Author: np
Date: Wed Jun 27 01:51:17 2018
New Revision: 335684
URL: https://svnweb.freebsd.org/changeset/base/335684

Log:
  cxgbe(4): Do not leak the filters in the hashfilter table on module
  unload.
  
  MFC after:    1 week
  Sponsored by: Chelsio Communications

Modified:
  head/sys/dev/cxgbe/adapter.h
  head/sys/dev/cxgbe/t4_filter.c
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/adapter.h
==============================================================================
--- head/sys/dev/cxgbe/adapter.h        Wed Jun 27 01:28:09 2018        
(r335683)
+++ head/sys/dev/cxgbe/adapter.h        Wed Jun 27 01:51:17 2018        
(r335684)
@@ -1260,6 +1260,7 @@ int t4_filter_rpl(struct sge_iq *, const struct rss_he
 int t4_hashfilter_ao_rpl(struct sge_iq *, const struct rss_header *, struct 
mbuf *);
 int t4_hashfilter_tcb_rpl(struct sge_iq *, const struct rss_header *, struct 
mbuf *);
 int t4_del_hashfilter_rpl(struct sge_iq *, const struct rss_header *, struct 
mbuf *);
+void free_hftid_tab(struct tid_info *);
 
 static inline struct wrqe *
 alloc_wrqe(int wr_len, struct sge_wrq *wrq)

Modified: head/sys/dev/cxgbe/t4_filter.c
==============================================================================
--- head/sys/dev/cxgbe/t4_filter.c      Wed Jun 27 01:28:09 2018        
(r335683)
+++ head/sys/dev/cxgbe/t4_filter.c      Wed Jun 27 01:51:17 2018        
(r335684)
@@ -70,6 +70,46 @@ static int set_hashfilter(struct adapter *, struct t4_
 static int del_hashfilter(struct adapter *, struct t4_filter *);
 static int configure_hashfilter_tcb(struct adapter *, struct filter_entry *);
 
+static int
+alloc_hftid_tab(struct tid_info *t, int flags)
+{
+
+       MPASS(t->ntids > 0);
+       MPASS(t->hftid_tab == NULL);
+
+       t->hftid_tab = malloc(sizeof(*t->hftid_tab) * t->ntids, M_CXGBE,
+           M_ZERO | flags);
+       if (t->hftid_tab == NULL)
+               return (ENOMEM);
+       mtx_init(&t->hftid_lock, "T4 hashfilters", 0, MTX_DEF);
+       cv_init(&t->hftid_cv, "t4hfcv");
+
+       return (0);
+}
+
+void
+free_hftid_tab(struct tid_info *t)
+{
+       int i;
+
+       if (t->hftid_tab != NULL) {
+               MPASS(t->ntids > 0);
+               for (i = 0; t->tids_in_use > 0 && i < t->ntids; i++) {
+                       if (t->hftid_tab[i] == NULL)
+                               continue;
+                       free(t->hftid_tab[i], M_CXGBE);
+                       t->tids_in_use--;
+               }
+               free(t->hftid_tab, M_CXGBE);
+               t->hftid_tab = NULL;
+       }
+
+       if (mtx_initialized(&t->hftid_lock)) {
+               mtx_destroy(&t->hftid_lock);
+               cv_destroy(&t->hftid_cv);
+       }
+}
+
 static void
 insert_hftid(struct adapter *sc, int tid, void *ctx, int ntids)
 {
@@ -653,14 +693,9 @@ set_filter(struct adapter *sc, struct t4_filter *t)
        }
        if (t->fs.hash) {
                if (__predict_false(ti->hftid_tab == NULL)) {
-                       ti->hftid_tab = malloc(sizeof(*ti->hftid_tab) * 
ti->ntids,
-                           M_CXGBE, M_NOWAIT | M_ZERO);
-                       if (ti->hftid_tab == NULL) {
-                               rc = ENOMEM;
+                       rc = alloc_hftid_tab(&sc->tids, M_NOWAIT);
+                       if (rc != 0)
                                goto done;
-                       }
-                       mtx_init(&ti->hftid_lock, "T4 hashfilters", 0, MTX_DEF);
-                       cv_init(&ti->hftid_cv, "t4hfcv");
                }
                if (__predict_false(sc->tids.atid_tab == NULL)) {
                        rc = alloc_atid_tab(&sc->tids, M_NOWAIT);

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c        Wed Jun 27 01:28:09 2018        
(r335683)
+++ head/sys/dev/cxgbe/t4_main.c        Wed Jun 27 01:51:17 2018        
(r335684)
@@ -1403,7 +1403,8 @@ t4_detach_common(device_t dev)
        free(sc->sge.iqmap, M_CXGBE);
        free(sc->sge.eqmap, M_CXGBE);
        free(sc->tids.ftid_tab, M_CXGBE);
-       free(sc->tids.hftid_tab, M_CXGBE);
+       if (sc->tids.hftid_tab)
+               free_hftid_tab(&sc->tids);
        free(sc->tids.atid_tab, M_CXGBE);
        free(sc->tids.tid_tab, M_CXGBE);
        free(sc->tt.tls_rx_ports, M_CXGBE);
@@ -1419,10 +1420,6 @@ t4_detach_common(device_t dev)
        if (mtx_initialized(&sc->tids.ftid_lock)) {
                mtx_destroy(&sc->tids.ftid_lock);
                cv_destroy(&sc->tids.ftid_cv);
-       }
-       if (mtx_initialized(&sc->tids.hftid_lock)) {
-               mtx_destroy(&sc->tids.hftid_lock);
-               cv_destroy(&sc->tids.hftid_cv);
        }
        if (mtx_initialized(&sc->tids.atid_lock))
                mtx_destroy(&sc->tids.atid_lock);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to