The do_move_pages_to_node() might return > 0 value, the number of pages
that are not migrated, then the value will be returned to userspace
directly. But, move_pages() syscall would just return 0 or errno. So,
we need reset the return value to 0 for such case as what pre-v4.17 did.
Fixes: a49bd4d71637 ("mm, numa: rework do_pages_move")
Cc: Michal Hocko <mhocko(a)suse.com>
Cc: Wei Yang <richardw.yang(a)linux.intel.com>
Cc: <stable(a)vger.kernel.org> [4.17+]
Signed-off-by: Yang Shi <yang.shi(a)linux.alibaba.com>
---
mm/migrate.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 86873b6..3e75432 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1659,8 +1659,11 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
goto out_flush;
err = do_move_pages_to_node(mm, &pagelist, current_node);
- if (err)
+ if (err) {
+ if (err > 0)
+ err = 0;
goto out;
+ }
if (i > start) {
err = store_status(status, start, current_node, i - start);
if (err)
--
1.8.3.1
The rtime compressor assumes that at least two bytes are
compressed.
If we try to compress just one byte, the loop condition will
wrap around and an out-of-bounds write happens.
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Richard Weinberger <richard(a)nod.at>
---
fs/jffs2/compr_rtime.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/jffs2/compr_rtime.c b/fs/jffs2/compr_rtime.c
index 406d9cc84ba8..cbf700001fc9 100644
--- a/fs/jffs2/compr_rtime.c
+++ b/fs/jffs2/compr_rtime.c
@@ -39,6 +39,9 @@ static int jffs2_rtime_compress(unsigned char *data_in,
memset(positions,0,sizeof(positions));
+ if (*dstlen < 2)
+ return -1;
+
while (pos < (*sourcelen) && outpos <= (*dstlen)-2) {
int backpos, runlen=0;
unsigned char value;
--
2.20.0
If compound is true, this means it is a PMD mapped THP. Which implies
the page is not linked to any defer list. So the first code chunk will
not be executed.
Also with this reason, it would not be proper to add this page to a
defer list. So the second code chunk is not correct.
Based on this, we should remove the defer list related code.
Fixes: 87eaceb3faa5 ("mm: thp: make deferred split shrinker memcg aware")
Signed-off-by: Wei Yang <richardw.yang(a)linux.intel.com>
Suggested-by: Kirill A. Shutemov <kirill.shutemov(a)linux.intel.com>
Cc: <stable(a)vger.kernel.org> [5.4+]
---
v4:
* finally we identified the related code is not necessary and not
correct, just remove it
* thanks to Kirill T first spot some problem
v3:
* remove all review/ack tag since rewrite the changelog
* use deferred_split_huge_page as the example of race
* add cc stable 5.4+ tag as suggested by David Rientjes
v2:
* move check on compound outside suggested by Alexander
* an example of the race condition, suggested by Michal
---
mm/memcontrol.c | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6c83cf4ed970..27c231bf4565 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5340,14 +5340,6 @@ static int mem_cgroup_move_account(struct page *page,
__mod_lruvec_state(to_vec, NR_WRITEBACK, nr_pages);
}
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
- if (compound && !list_empty(page_deferred_list(page))) {
- spin_lock(&from->deferred_split_queue.split_queue_lock);
- list_del_init(page_deferred_list(page));
- from->deferred_split_queue.split_queue_len--;
- spin_unlock(&from->deferred_split_queue.split_queue_lock);
- }
-#endif
/*
* It is safe to change page->mem_cgroup here because the page
* is referenced, charged, and isolated - we can't race with
@@ -5357,16 +5349,6 @@ static int mem_cgroup_move_account(struct page *page,
/* caller should have done css_get */
page->mem_cgroup = to;
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
- if (compound && list_empty(page_deferred_list(page))) {
- spin_lock(&to->deferred_split_queue.split_queue_lock);
- list_add_tail(page_deferred_list(page),
- &to->deferred_split_queue.split_queue);
- to->deferred_split_queue.split_queue_len++;
- spin_unlock(&to->deferred_split_queue.split_queue_lock);
- }
-#endif
-
spin_unlock_irqrestore(&from->move_lock, flags);
ret = 0;
--
2.17.1
Since commit a49bd4d71637 ("mm, numa: rework do_pages_move"),
the semantic of move_pages() was changed to return the number of
non-migrated pages (failed to migration) and the call would be aborted
immediately if migrate_pages() returns positive value. But it didn't
report the number of pages that we even haven't attempted to migrate.
So, fix it by including non-attempted pages in the return value.
Fixes: a49bd4d71637 ("mm, numa: rework do_pages_move")
Suggested-by: Michal Hocko <mhocko(a)suse.com>
Cc: Wei Yang <richardw.yang(a)linux.intel.com>
Cc: <stable(a)vger.kernel.org> [4.17+]
Signed-off-by: Yang Shi <yang.shi(a)linux.alibaba.com>
---
The patch is based off Wei Yang's cleanup patchset:
https://lore.kernel.org/linux-mm/20200122011647.13636-1-richardw.yang@linux…
mm/migrate.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 591f2e5..51b1b76 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1582,7 +1582,7 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
static int move_pages_and_store_status(struct mm_struct *mm, int node,
struct list_head *pagelist, int __user *status,
- int start, int nr)
+ int start, int nr, unsigned long total)
{
int err;
@@ -1590,8 +1590,17 @@ static int move_pages_and_store_status(struct mm_struct *mm, int node,
return 0;
err = do_move_pages_to_node(mm, pagelist, node);
- if (err)
+ if (err) {
+ /*
+ * Possitive err means the number of failed pages to
+ * migrate. Since we are going to abort and return the
+ * number of non-migrated pages, so need incude the rest
+ * of the nr_pages that are not attempted as well.
+ */
+ if (err > 0)
+ err += total - start - nr - 1;
return err;
+ }
err = store_status(status, start, node, nr);
return err;
}
@@ -1640,7 +1649,8 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
start = i;
} else if (node != current_node) {
err = move_pages_and_store_status(mm, current_node,
- &pagelist, status, start, i - start);
+ &pagelist, status, start, i - start,
+ nr_pages);
if (err)
goto out;
start = i;
@@ -1670,7 +1680,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
goto out_flush;
err = move_pages_and_store_status(mm, current_node, &pagelist,
- status, start, i - start);
+ status, start, i - start, nr_pages);
if (err)
goto out;
current_node = NUMA_NO_NODE;
@@ -1678,7 +1688,7 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes,
out_flush:
/* Make sure we do not overwrite the existing error */
err1 = move_pages_and_store_status(mm, current_node, &pagelist,
- status, start, i - start);
+ status, start, i - start, nr_pages);
if (err >= 0)
err = err1;
out:
--
1.8.3.1
[Why]
This patch is trying to address the issue observed when hotplug DP
daisy chain monitors.
e.g.
src-mstb-mstb-sst -> src (unplug) mstb-mstb-sst -> src-mstb-mstb-sst
(plug in again)
Once unplug a DP MST capable device, driver will call
drm_dp_mst_topology_mgr_set_mst() to disable MST. In this function,
it cleans data of topology manager while disabling mst_state. However,
it doesn't clean up the proposed_vcpis of topology manager.
If proposed_vcpi is not reset, once plug in MST daisy chain monitors
later, code will fail at checking port validation while trying to
allocate payloads.
When MST capable device is plugged in again and try to allocate
payloads by calling drm_dp_update_payload_part1(), this
function will iterate over all proposed virtual channels to see if
any proposed VCPI's num_slots is greater than 0. If any proposed
VCPI's num_slots is greater than 0 and the port which the
specific virtual channel directed to is not in the topology, code then
fails at the port validation. Since there are stale VCPI allocations
from the previous topology enablement in proposed_vcpi[], code will fail
at port validation and reurn EINVAL.
[How]
Clean up the data of stale proposed_vcpi[] and reset mgr->proposed_vcpis
to NULL while disabling mst in drm_dp_mst_topology_mgr_set_mst().
Changes since v1:
*Add on more details in commit message to describe the issue which the
patch is trying to fix
Signed-off-by: Wayne Lin <Wayne.Lin(a)amd.com>
---
drivers/gpu/drm/drm_dp_mst_topology.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index ae5809a1f19a..bf4f745a4edb 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -3386,6 +3386,7 @@ static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8 dp_link_count)
int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state)
{
int ret = 0;
+ int i = 0;
struct drm_dp_mst_branch *mstb = NULL;
mutex_lock(&mgr->lock);
@@ -3446,10 +3447,21 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms
/* this can fail if the device is gone */
drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0);
ret = 0;
+ mutex_lock(&mgr->payload_lock);
memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload));
mgr->payload_mask = 0;
set_bit(0, &mgr->payload_mask);
+ for (i = 0; i < mgr->max_payloads; i++) {
+ struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i];
+
+ if (vcpi) {
+ vcpi->vcpi = 0;
+ vcpi->num_slots = 0;
+ }
+ mgr->proposed_vcpis[i] = NULL;
+ }
mgr->vcpi_mask = 0;
+ mutex_unlock(&mgr->payload_lock);
}
out_unlock:
--
2.17.1
+Xiaochen (author of the patch)
On 1/21/2020 6:26 PM, Sasha Levin wrote:
> Hi,
>
> [This is an automated email]
>
> This commit has been processed because it contains a "Fixes:" tag,
> fixing commit: c7d9aac61311 ("x86/intel_rdt/cqm: Add mkdir support for RDT monitoring").
>
> The bot has tested the following trees: v5.4.13, v4.19.97, v4.14.166.
>
> v5.4.13: Build OK!
> v4.19.97: Failed to apply! Possible dependencies:
> Unable to calculate
>
> v4.14.166: Failed to apply! Possible dependencies:
> cfd0f34e4cd5 ("x86/intel_rdt: Add diagnostics when making directories")
>
>
> NOTE: The patch will not be queued to stable trees until it is upstream.
>
> How should we proceed with this patch?
>