aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/iwm
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2016-06-23 01:11:52 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2016-06-23 01:11:52 +0000
commit8a1660e16af6369a5f8f0193b8b46e9be86b757f (patch)
treea2ef0cc4ea4f5f5cb627f2f8d4a4218e540329a4 /sys/dev/iwm
parentf6ea76fb7eb845154f228267f4173988745ec346 (diff)
downloadsrc-8a1660e16af6369a5f8f0193b8b46e9be86b757f.tar.gz
src-8a1660e16af6369a5f8f0193b8b46e9be86b757f.zip
[iwm] Add and use iwm_phy_db_free(), to plug phy_db memory leak.
(Together with other iwm(4) memory leak fixes) Memory leakage in M_DEVBUF is now at ca. 2KB for each iwm(4) module load/unload cycle. Submitted by: Imre Vadasz <imre@vdsz.com> Approved by: re (gjb) Obtained from: DragonflyBSD git eaf551a1d464c643e98ce5781971dd32124e9af1 Differential Revision: https://reviews.freebsd.org/D6819
Notes
Notes: svn path=/head/; revision=302103
Diffstat (limited to 'sys/dev/iwm')
-rw-r--r--sys/dev/iwm/if_iwm.c2
-rw-r--r--sys/dev/iwm/if_iwm_phy_db.c30
-rw-r--r--sys/dev/iwm/if_iwm_phy_db.h1
3 files changed, 33 insertions, 0 deletions
diff --git a/sys/dev/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
index 823de012b775..dbd1eeff8507 100644
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -5014,6 +5014,8 @@ iwm_detach_local(struct iwm_softc *sc, int do_net80211)
if (do_net80211)
ieee80211_ifdetach(&sc->sc_ic);
+ iwm_phy_db_free(sc);
+
/* Free descriptor rings */
iwm_free_rx_ring(sc, &sc->rxq);
for (i = 0; i < nitems(sc->txq); i++)
diff --git a/sys/dev/iwm/if_iwm_phy_db.c b/sys/dev/iwm/if_iwm_phy_db.c
index ae335b3c49a4..42d891466cdf 100644
--- a/sys/dev/iwm/if_iwm_phy_db.c
+++ b/sys/dev/iwm/if_iwm_phy_db.c
@@ -451,3 +451,33 @@ iwm_send_phy_db_data(struct iwm_softc *sc)
__func__);
return 0;
}
+
+static void
+iwm_phy_db_free_section(struct iwm_softc *sc,
+ enum iwm_phy_db_section_type type, uint16_t chg_id)
+{
+ struct iwm_phy_db_entry *entry =
+ iwm_phy_db_get_section(sc, type, chg_id);
+ if (!entry)
+ return;
+
+ if (entry->data != NULL)
+ free(entry->data, M_DEVBUF);
+ entry->data = NULL;
+ entry->size = 0;
+}
+
+void
+iwm_phy_db_free(struct iwm_softc *sc)
+{
+ int i;
+
+ iwm_phy_db_free_section(sc, IWM_PHY_DB_CFG, 0);
+ iwm_phy_db_free_section(sc, IWM_PHY_DB_CALIB_NCH, 0);
+
+ for (i = 0; i < IWM_NUM_PAPD_CH_GROUPS; i++)
+ iwm_phy_db_free_section(sc, IWM_PHY_DB_CALIB_CHG_PAPD, i);
+
+ for (i = 0; i < IWM_NUM_TXP_CH_GROUPS; i++)
+ iwm_phy_db_free_section(sc, IWM_PHY_DB_CALIB_CHG_TXP, i);
+}
diff --git a/sys/dev/iwm/if_iwm_phy_db.h b/sys/dev/iwm/if_iwm_phy_db.h
index a1de22032dc4..63ccdee59353 100644
--- a/sys/dev/iwm/if_iwm_phy_db.h
+++ b/sys/dev/iwm/if_iwm_phy_db.h
@@ -109,4 +109,5 @@
extern int iwm_phy_db_set_section(struct iwm_softc *sc,
struct iwm_calib_res_notif_phy_db *phy_db_notif);
extern int iwm_send_phy_db_data(struct iwm_softc *sc);
+extern void iwm_phy_db_free(struct iwm_softc *sc);
#endif /* __IF_IWM_PHY_DB_H__ */