aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ipw2x00
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2010-03-08 00:18:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-03-10 16:16:55 -0500
commit8e59340e4fb65cfd748eaa1e23db057c52520f35 (patch)
treed302d7fc27edf87c78e50ee24608554240d99dec /drivers/net/wireless/ipw2x00
parent38a679a52be13d5a0c766597ab823e06688d6e8e (diff)
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=14989 Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ipw2x00')
-rw-r--r--drivers/net/wireless/ipw2x00/libipw.h2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c37
2 files changed, 18 insertions, 21 deletions
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h
index bf45391172f3..a6d5e42647e4 100644
--- a/drivers/net/wireless/ipw2x00/libipw.h
+++ b/drivers/net/wireless/ipw2x00/libipw.h
@@ -797,7 +797,7 @@ struct libipw_device {
797 /* Probe / Beacon management */ 797 /* Probe / Beacon management */
798 struct list_head network_free_list; 798 struct list_head network_free_list;
799 struct list_head network_list; 799 struct list_head network_list;
800 struct libipw_network *networks; 800 struct libipw_network *networks[MAX_NETWORK_COUNT];
801 int scans; 801 int scans;
802 int scan_age; 802 int scan_age;
803 803
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 1ae0b2b02c38..2fa55867bd8b 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -67,16 +67,17 @@ void *libipw_wiphy_privid = &libipw_wiphy_privid;
67 67
68static int libipw_networks_allocate(struct libipw_device *ieee) 68static int libipw_networks_allocate(struct libipw_device *ieee)
69{ 69{
70 if (ieee->networks) 70 int i, j;
71 return 0; 71
72 72 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
73 ieee->networks = 73 ieee->networks[i] = kzalloc(sizeof(struct libipw_network),
74 kzalloc(MAX_NETWORK_COUNT * sizeof(struct libipw_network), 74 GFP_KERNEL);
75 GFP_KERNEL); 75 if (!ieee->networks[i]) {
76 if (!ieee->networks) { 76 LIBIPW_ERROR("Out of memory allocating beacons\n");
77 printk(KERN_WARNING "%s: Out of memory allocating beacons\n", 77 for (j = 0; j < i; j++)
78 ieee->dev->name); 78 kfree(ieee->networks[j]);
79 return -ENOMEM; 79 return -ENOMEM;
80 }
80 } 81 }
81 82
82 return 0; 83 return 0;
@@ -97,15 +98,11 @@ static inline void libipw_networks_free(struct libipw_device *ieee)
97{ 98{
98 int i; 99 int i;
99 100
100 if (!ieee->networks) 101 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
101 return; 102 if (ieee->networks[i]->ibss_dfs)
102 103 kfree(ieee->networks[i]->ibss_dfs);
103 for (i = 0; i < MAX_NETWORK_COUNT; i++) 104 kfree(ieee->networks[i]);
104 if (ieee->networks[i].ibss_dfs) 105 }
105 kfree(ieee->networks[i].ibss_dfs);
106
107 kfree(ieee->networks);
108 ieee->networks = NULL;
109} 106}
110 107
111void libipw_networks_age(struct libipw_device *ieee, 108void libipw_networks_age(struct libipw_device *ieee,
@@ -130,7 +127,7 @@ static void libipw_networks_initialize(struct libipw_device *ieee)
130 INIT_LIST_HEAD(&ieee->network_free_list); 127 INIT_LIST_HEAD(&ieee->network_free_list);
131 INIT_LIST_HEAD(&ieee->network_list); 128 INIT_LIST_HEAD(&ieee->network_list);
132 for (i = 0; i < MAX_NETWORK_COUNT; i++) 129 for (i = 0; i < MAX_NETWORK_COUNT; i++)
133 list_add_tail(&ieee->networks[i].list, 130 list_add_tail(&ieee->networks[i]->list,
134 &ieee->network_free_list); 131 &ieee->network_free_list);
135} 132}
136 133