Commit 8e59340e authored by Zhu Yi's avatar Zhu Yi Committed by John W. Linville

libipw: split ieee->networks into small pieces

The ieee->networks consists of 128 struct libipw_network entries. If
we allocate this chunk of memory altogether, it ends up with an
order 4 page allocation. High order page allocation is likely to fail
on system high load. This patch splits the big chunk memory allocation
into small pieces, each is 344 bytes, allocates them with 128 times.

The patch fixed bug http://bugzilla.kernel.org/show_bug.cgi?id=14989Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 38a679a5
...@@ -797,7 +797,7 @@ struct libipw_device { ...@@ -797,7 +797,7 @@ struct libipw_device {
/* Probe / Beacon management */ /* Probe / Beacon management */
struct list_head network_free_list; struct list_head network_free_list;
struct list_head network_list; struct list_head network_list;
struct libipw_network *networks; struct libipw_network *networks[MAX_NETWORK_COUNT];
int scans; int scans;
int scan_age; int scan_age;
......
...@@ -67,17 +67,18 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid; ...@@ -67,17 +67,18 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid;
static int libipw_networks_allocate(struct libipw_device *ieee) static int libipw_networks_allocate(struct libipw_device *ieee)
{ {
if (ieee->networks) int i, j;
return 0;
ieee->networks = for (i = 0; i < MAX_NETWORK_COUNT; i++) {
kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
GFP_KERNEL); GFP_KERNEL);
if (!ieee->networks) { if (!ieee->networks[i]) {
printk(KERN_WARNING "%s: Out of memory allocating beacons\n", LIBIPW_ERROR("Out of memory allocating beacons\n");
ieee->dev->name); for (j = 0; j < i; j++)
kfree(ieee->networks[j]);
return -ENOMEM; return -ENOMEM;
} }
}
return 0; return 0;
} }
...@@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee) ...@@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
{ {
int i; int i;
if (!ieee->networks) for (i = 0; i < MAX_NETWORK_COUNT; i++) {
return; if (ieee->networks[i]->ibss_dfs)
kfree(ieee->networks[i]->ibss_dfs);
for (i = 0; i < MAX_NETWORK_COUNT; i++) kfree(ieee->networks[i]);
if (ieee->networks[i].ibss_dfs) }
kfree(ieee->networks[i].ibss_dfs);
kfree(ieee->networks);
ieee->networks = NULL;
} }
void libipw_networks_age(struct libipw_device *ieee, void libipw_networks_age(struct libipw_device *ieee,
...@@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee) ...@@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
INIT_LIST_HEAD(&ieee->network_free_list); INIT_LIST_HEAD(&ieee->network_free_list);
INIT_LIST_HEAD(&ieee->network_list); INIT_LIST_HEAD(&ieee->network_list);
for (i = 0; i < MAX_NETWORK_COUNT; i++) for (i = 0; i < MAX_NETWORK_COUNT; i++)
list_add_tail(&ieee->networks[i].list, list_add_tail(&ieee->networks[i]->list,
&ieee->network_free_list); &ieee->network_free_list);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment