Skip to content

Commit

Permalink
libipw: split ieee->networks into small pieces
Browse files Browse the repository at this point in the history
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=14989

Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Zhu Yi authored and John W. Linville committed Mar 10, 2010
1 parent 38a679a commit 8e59340
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 21 deletions.
2 changes: 1 addition & 1 deletion drivers/net/wireless/ipw2x00/libipw.h
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ struct libipw_device {
/* Probe / Beacon management */
struct list_head network_free_list;
struct list_head network_list;
struct libipw_network *networks;
struct libipw_network *networks[MAX_NETWORK_COUNT];
int scans;
int scan_age;

Expand Down
37 changes: 17 additions & 20 deletions drivers/net/wireless/ipw2x00/libipw_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid;

static int libipw_networks_allocate(struct libipw_device *ieee)
{
if (ieee->networks)
return 0;

ieee->networks =
kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network),
GFP_KERNEL);
if (!ieee->networks) {
printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
ieee->dev->name);
return -ENOMEM;
int i, j;

for (i = 0; i < MAX_NETWORK_COUNT; i++) {
ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
GFP_KERNEL);
if (!ieee->networks[i]) {
LIBIPW_ERROR("Out of memory allocating beacons\n");
for (j = 0; j < i; j++)
kfree(ieee->networks[j]);
return -ENOMEM;
}
}

return 0;
Expand All @@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
{
int i;

if (!ieee->networks)
return;

for (i = 0; i < MAX_NETWORK_COUNT; i++)
if (ieee->networks[i].ibss_dfs)
kfree(ieee->networks[i].ibss_dfs);

kfree(ieee->networks);
ieee->networks = NULL;
for (i = 0; i < MAX_NETWORK_COUNT; i++) {
if (ieee->networks[i]->ibss_dfs)
kfree(ieee->networks[i]->ibss_dfs);
kfree(ieee->networks[i]);
}
}

void libipw_networks_age(struct libipw_device *ieee,
Expand All @@ -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_list);
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);
}

Expand Down

0 comments on commit 8e59340

Please sign in to comment.