From 047e7d590ef85a4e2723bc37a02efb60b63a32b6 Mon Sep 17 00:00:00 2001 From: Krishna Kumaar Natarajan Date: Thu, 11 Feb 2016 16:30:02 -0800 Subject: [PATCH] qcacld-3.0: Redefine dfs data structure to fix prealloc size concern Redefine dfs filter type to avoid prealloc problem by making one large chunk into multiple smaller chunks. With current data structure, dfs attach was requesting huge chunk of memory from the heap which results in failure. This change set fixes the issue by modifying the data structure so that one large chunk is made as multiple smaller chunks. Change-Id: If944747de63a68d55a83b8595d0a07dd05f53dbe CRs-Fixed: 975903 --- core/sap/dfs/inc/dfs.h | 2 +- core/sap/dfs/src/dfs.c | 70 +++++++++++++++++++++-- core/sap/dfs/src/dfs_debug.c | 2 +- core/sap/dfs/src/dfs_init.c | 4 +- core/sap/dfs/src/dfs_process_radarevent.c | 2 +- 5 files changed, 69 insertions(+), 11 deletions(-) diff --git a/core/sap/dfs/inc/dfs.h b/core/sap/dfs/inc/dfs.h index c367eec4dbcf..56187cbcdc8b 100644 --- a/core/sap/dfs/inc/dfs.h +++ b/core/sap/dfs/inc/dfs.h @@ -390,7 +390,7 @@ struct dfs_filter { #endif struct dfs_filtertype { - struct dfs_filter ft_filters[DFS_MAX_NUM_RADAR_FILTERS]; + struct dfs_filter *ft_filters[DFS_MAX_NUM_RADAR_FILTERS]; /* Duration of pulse which specifies filter type */ uint32_t ft_filterdur; /* Num filters of this type */ diff --git a/core/sap/dfs/src/dfs.c b/core/sap/dfs/src/dfs.c index 4d7fbbc4ff65..d938c0124931 100644 --- a/core/sap/dfs/src/dfs.c +++ b/core/sap/dfs/src/dfs.c @@ -215,6 +215,44 @@ static int dfs_get_debug_info(struct ieee80211com *ic, int type, void *data) return (int)dfs->dfs_proc_phyerr; } +/** + * dfs_alloc_mem_filter() - allocate memory for dfs ft_filters + * @radarf: pointer holding ft_filters + * + * Return: 0-success and 1-failure +*/ +static int dfs_alloc_mem_filter(struct dfs_filtertype *radarf) +{ + int status = 0, n, i; + + for (i = 0; i < DFS_MAX_NUM_RADAR_FILTERS; i++) { + radarf->ft_filters[i] = qdf_mem_malloc(sizeof(struct + dfs_filter)); + if (NULL == radarf->ft_filters[i]) { + DFS_PRINTK("%s[%d]: mem alloc failed\n", + __func__, __LINE__); + status = 1; + goto error; + } + } + + return status; + +error: + /* free up allocated memory */ + for (n = 0; n < i; n++) { + if (radarf->ft_filters[n]) { + qdf_mem_free(radarf->ft_filters[n]); + radarf->ft_filters[i] = NULL; + } + } + + DFS_PRINTK("%s[%d]: cannot allocate memory for radar filter types\n", + __func__, __LINE__); + + return status; +} + int dfs_attach(struct ieee80211com *ic) { int i, n; @@ -325,18 +363,20 @@ int dfs_attach(struct ieee80211com *ic) /* Allocate memory for radar filters */ for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) { - dfs->dfs_radarf[n] = - (struct dfs_filtertype *)os_malloc(NULL, - sizeof(struct - dfs_filtertype), - GFP_ATOMIC); + dfs->dfs_radarf[n] = (struct dfs_filtertype *) + os_malloc(NULL, sizeof(struct dfs_filtertype), + GFP_ATOMIC); if (dfs->dfs_radarf[n] == NULL) { DFS_PRINTK ("%s: cannot allocate memory for radar filter types\n", __func__); goto bad1; + } else { + qdf_mem_zero(dfs->dfs_radarf[n], + sizeof(struct dfs_filtertype)); + if (0 != dfs_alloc_mem_filter(dfs->dfs_radarf[n])) + goto bad1; } - OS_MEMZERO(dfs->dfs_radarf[n], sizeof(struct dfs_filtertype)); } /* Allocate memory for radar table */ dfs->dfs_radartable = @@ -431,6 +471,23 @@ bad1: #undef N } +/** + * dfs_free_filter() - free memory allocated for dfs ft_filters + * @radarf: pointer holding ft_filters + * + * Return: NA +*/ +static void dfs_free_filter(struct dfs_filtertype *radarf) +{ + int i; + + for (i = 0; i < DFS_MAX_NUM_RADAR_FILTERS; i++) { + if (radarf->ft_filters[i]) { + qdf_mem_free(radarf->ft_filters[i]); + radarf->ft_filters[i] = NULL; + } + } +} void dfs_detach(struct ieee80211com *ic) { struct ath_dfs *dfs = (struct ath_dfs *)ic->ic_dfs; @@ -496,6 +553,7 @@ void dfs_detach(struct ieee80211com *ic) for (n = 0; n < DFS_MAX_RADAR_TYPES; n++) { if (dfs->dfs_radarf[n] != NULL) { + dfs_free_filter(dfs->dfs_radarf[n]); OS_FREE(dfs->dfs_radarf[n]); dfs->dfs_radarf[n] = NULL; } diff --git a/core/sap/dfs/src/dfs_debug.c b/core/sap/dfs/src/dfs_debug.c index 71f917ad00e6..1a5aa2be2e98 100644 --- a/core/sap/dfs/src/dfs_debug.c +++ b/core/sap/dfs/src/dfs_debug.c @@ -108,7 +108,7 @@ void dfs_print_filters(struct ath_dfs *dfs) ("===========ft->ft_numfilters=%u===========\n", ft->ft_numfilters); for (j = 0; j < ft->ft_numfilters; j++) { - rf = &(ft->ft_filters[j]); + rf = ft->ft_filters[j]; DFS_PRINTK ("filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n", j, rf->rf_pulseid, rf->rf_numpulses, diff --git a/core/sap/dfs/src/dfs_init.c b/core/sap/dfs/src/dfs_init.c index b4db534a0ade..c67f7fcf1b03 100644 --- a/core/sap/dfs/src/dfs_init.c +++ b/core/sap/dfs/src/dfs_init.c @@ -118,7 +118,7 @@ void dfs_reset_alldelaylines(struct ath_dfs *dfs, int seg_id) ft = dfs->dfs_radarf[i]; if (NULL != ft) { for (j = 0; j < ft->ft_numfilters; j++) { - rf = &(ft->ft_filters[j]); + rf = ft->ft_filters[j]; if (dfs->ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) dl = (seg_id == 0) ? @@ -332,7 +332,7 @@ int dfs_init_radar_filters(struct ieee80211com *ic, } dfs->dfs_rinfo.rn_numradars++; } - rf = &(ft->ft_filters[ft->ft_numfilters++]); + rf = ft->ft_filters[ft->ft_numfilters++]; dfs_reset_delayline(&rf->rf_dl); if (ic->dfs_hw_bd_id != DFS_HWBD_QCA6174) diff --git a/core/sap/dfs/src/dfs_process_radarevent.c b/core/sap/dfs/src/dfs_process_radarevent.c index 6c4613b19a82..321161c197a4 100644 --- a/core/sap/dfs/src/dfs_process_radarevent.c +++ b/core/sap/dfs/src/dfs_process_radarevent.c @@ -634,7 +634,7 @@ int dfs_process_radarevent(struct ath_dfs *dfs, } for (p = 0, found = 0; (p < ft->ft_numfilters) && (!found); p++) { - rf = &(ft->ft_filters[p]); + rf = ft->ft_filters[p]; dl = (seg_id == 0) ? &rf->rf_dl : &rf->rf_dl_ext_seg; if ((re.re_dur >= rf->rf_mindur)