summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-03-08 00:54:04 +0100
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2020-03-08 00:54:04 +0100
commitf2c1392ff3473a396e4d177ff5ad368b9d6cd211 (patch)
tree2111e8c1e50e3fa56fc46bd4e80e5a577459e768 /mm
parentb16d3d60b112c8cb90ebcd7ae97a5d2207d6f43c (diff)
parente0f8b8a65a473a8baa439cf865a694bbeb83fe90 (diff)
Merge tag 'v4.14.170' into 4.14-2.3.x-imx
This is the 4.14.170 stable release Conflicts: drivers/net/phy/phy_device.c drivers/tty/serial/imx.c include/linux/platform_data/dma-imx-sdma.h net/wireless/util.c
Diffstat (limited to 'mm')
-rw-r--r--mm/huge_memory.c38
-rw-r--r--mm/mempolicy.c6
-rw-r--r--mm/page-writeback.c4
-rw-r--r--mm/shmem.c7
4 files changed, 33 insertions, 22 deletions
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 1adc2e6c50f9..92915cc87549 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -502,13 +502,13 @@ void prep_transhuge_page(struct page *page)
set_compound_page_dtor(page, TRANSHUGE_PAGE_DTOR);
}
-unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len,
+static unsigned long __thp_get_unmapped_area(struct file *filp,
+ unsigned long addr, unsigned long len,
loff_t off, unsigned long flags, unsigned long size)
{
- unsigned long addr;
loff_t off_end = off + len;
loff_t off_align = round_up(off, size);
- unsigned long len_pad;
+ unsigned long len_pad, ret;
if (off_end <= off_align || (off_end - off_align) < size)
return 0;
@@ -517,30 +517,40 @@ unsigned long __thp_get_unmapped_area(struct file *filp, unsigned long len,
if (len_pad < len || (off + len_pad) < off)
return 0;
- addr = current->mm->get_unmapped_area(filp, 0, len_pad,
+ ret = current->mm->get_unmapped_area(filp, addr, len_pad,
off >> PAGE_SHIFT, flags);
- if (IS_ERR_VALUE(addr))
+
+ /*
+ * The failure might be due to length padding. The caller will retry
+ * without the padding.
+ */
+ if (IS_ERR_VALUE(ret))
return 0;
- addr += (off - addr) & (size - 1);
- return addr;
+ /*
+ * Do not try to align to THP boundary if allocation at the address
+ * hint succeeds.
+ */
+ if (ret == addr)
+ return addr;
+
+ ret += (off - ret) & (size - 1);
+ return ret;
}
unsigned long thp_get_unmapped_area(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
+ unsigned long ret;
loff_t off = (loff_t)pgoff << PAGE_SHIFT;
- if (addr)
- goto out;
if (!IS_DAX(filp->f_mapping->host) || !IS_ENABLED(CONFIG_FS_DAX_PMD))
goto out;
- addr = __thp_get_unmapped_area(filp, len, off, flags, PMD_SIZE);
- if (addr)
- return addr;
-
- out:
+ ret = __thp_get_unmapped_area(filp, addr, len, off, flags, PMD_SIZE);
+ if (ret)
+ return ret;
+out:
return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags);
}
EXPORT_SYMBOL_GPL(thp_get_unmapped_area);
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index a37cfa88669e..1b34f2e35951 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -2724,6 +2724,9 @@ int mpol_parse_str(char *str, struct mempolicy **mpol)
char *flags = strchr(str, '=');
int err = 1;
+ if (flags)
+ *flags++ = '\0'; /* terminate mode string */
+
if (nodelist) {
/* NUL-terminate mode or flags string */
*nodelist++ = '\0';
@@ -2734,9 +2737,6 @@ int mpol_parse_str(char *str, struct mempolicy **mpol)
} else
nodes_clear(nodes);
- if (flags)
- *flags++ = '\0'; /* terminate mode string */
-
for (mode = 0; mode < MPOL_MAX; mode++) {
if (!strcmp(str, policy_modes[mode])) {
break;
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a40c075fd8f1..29f9980c13ac 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -201,11 +201,11 @@ static void wb_min_max_ratio(struct bdi_writeback *wb,
if (this_bw < tot_bw) {
if (min) {
min *= this_bw;
- do_div(min, tot_bw);
+ min = div64_ul(min, tot_bw);
}
if (max < 100) {
max *= this_bw;
- do_div(max, tot_bw);
+ max = div64_ul(max, tot_bw);
}
}
diff --git a/mm/shmem.c b/mm/shmem.c
index 69106c600692..0b6db162083c 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2052,9 +2052,10 @@ unsigned long shmem_get_unmapped_area(struct file *file,
/*
* Our priority is to support MAP_SHARED mapped hugely;
* and support MAP_PRIVATE mapped hugely too, until it is COWed.
- * But if caller specified an address hint, respect that as before.
+ * But if caller specified an address hint and we allocated area there
+ * successfully, respect that as before.
*/
- if (uaddr)
+ if (uaddr == addr)
return addr;
if (shmem_huge != SHMEM_HUGE_FORCE) {
@@ -2088,7 +2089,7 @@ unsigned long shmem_get_unmapped_area(struct file *file,
if (inflated_len < len)
return addr;
- inflated_addr = get_area(NULL, 0, inflated_len, 0, flags);
+ inflated_addr = get_area(NULL, uaddr, inflated_len, 0, flags);
if (IS_ERR_VALUE(inflated_addr))
return addr;
if (inflated_addr & ~PAGE_MASK)