summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-05-20 05:26:43 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-06-10 13:20:36 -0400
commitddaf29fd9bb6a8192153bc097615765d202b0ab3 (patch)
tree645a403be079231588e7b34bbd4edf8298df2020
parent64ae0e71c60dc4bd3a59ae709b807f96f68df495 (diff)
firmware: Free temporary page table after vmapping
Once after performing vmap() to map the S/G pages, our own page table becomes superfluous since the pages can be released via vfree() automatically. Let's change the buffer release code and discard the page table array for saving some memory. Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/base/firmware_loader/fallback.c7
-rw-r--r--drivers/base/firmware_loader/main.c6
2 files changed, 9 insertions, 4 deletions
diff --git a/drivers/base/firmware_loader/fallback.c b/drivers/base/firmware_loader/fallback.c
index f962488546b6..a0a1856aac84 100644
--- a/drivers/base/firmware_loader/fallback.c
+++ b/drivers/base/firmware_loader/fallback.c
@@ -222,7 +222,7 @@ static ssize_t firmware_loading_show(struct device *dev,
222/* one pages buffer should be mapped/unmapped only once */ 222/* one pages buffer should be mapped/unmapped only once */
223static int map_fw_priv_pages(struct fw_priv *fw_priv) 223static int map_fw_priv_pages(struct fw_priv *fw_priv)
224{ 224{
225 if (!fw_priv->is_paged_buf) 225 if (!fw_priv->pages)
226 return 0; 226 return 0;
227 227
228 vunmap(fw_priv->data); 228 vunmap(fw_priv->data);
@@ -230,6 +230,11 @@ static int map_fw_priv_pages(struct fw_priv *fw_priv)
230 PAGE_KERNEL_RO); 230 PAGE_KERNEL_RO);
231 if (!fw_priv->data) 231 if (!fw_priv->data)
232 return -ENOMEM; 232 return -ENOMEM;
233
234 /* page table is no longer needed after mapping, let's free */
235 vfree(fw_priv->pages);
236 fw_priv->pages = NULL;
237
233 return 0; 238 return 0;
234} 239}
235 240
diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c
index 7eaaf5ee5ba6..aed1a7c56713 100644
--- a/drivers/base/firmware_loader/main.c
+++ b/drivers/base/firmware_loader/main.c
@@ -252,13 +252,13 @@ static void __free_fw_priv(struct kref *ref)
252 spin_unlock(&fwc->lock); 252 spin_unlock(&fwc->lock);
253 253
254#ifdef CONFIG_FW_LOADER_USER_HELPER 254#ifdef CONFIG_FW_LOADER_USER_HELPER
255 if (fw_priv->is_paged_buf) { 255 if (fw_priv->pages) {
256 /* free leftover pages */
256 int i; 257 int i;
257 vunmap(fw_priv->data);
258 for (i = 0; i < fw_priv->nr_pages; i++) 258 for (i = 0; i < fw_priv->nr_pages; i++)
259 __free_page(fw_priv->pages[i]); 259 __free_page(fw_priv->pages[i]);
260 vfree(fw_priv->pages); 260 vfree(fw_priv->pages);
261 } else 261 }
262#endif 262#endif
263 if (!fw_priv->allocated_size) 263 if (!fw_priv->allocated_size)
264 vfree(fw_priv->data); 264 vfree(fw_priv->data);