mm/shmem: fix THP allocation and fallback loop
Subsystems (3)
PATCH v3 1/1 mm/shmem: fix THP allocation and fallback loop
From: Kairui Song <[email protected]>
The order check and fallback loop is updating the index value on every loop, this will cause the index to be wrongly aligned by a larger value while the loop shrinks the order.
This may result in inserting and returning a folio of the wrong index and cause data corruption with some userspace workloads [1].
---
Changes from V2:
- Introduce a temporary variable to improve code,
no behavior change, generated code is identical.
- Link to V2: https://lore.kernel.org/linux-mm/[email protected]/
Changes from V1:
- Remove unnecessary cleanup and simplify the commit message.
- Link to V1: https://lore.kernel.org/linux-mm/[email protected]/
--- mm/shmem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
mm/shmem.c +6 -3
@@ -1882,6 +1882,7 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf,struct shmem_inode_info *info =SHMEM_I (inode);unsigned long suitable_orders =0 ;struct folio *folio =NULL ; +pgoff_t aligned_index;long pages;int error, order;
@@ -1895,10 +1896,12 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, order =highest_order (suitable_orders);while (suitable_orders) { pages =1UL << order; - index =round_down (index, pages); - folio =shmem_alloc_folio (gfp, order, info, index); -if (folio) + aligned_index =round_down (index, pages); + folio =shmem_alloc_folio (gfp, order, info, aligned_index); +if (folio) { + index = aligned_index; goto allocated; + }if (pages ==HPAGE_PMD_NR )count_vm_event (THP_FILE_FALLBACK );
Signature · 1 line
2.51.0
Quoted 44 lines · Kairui Song
From: Kairui Song <[email protected]>
The order check and fallback loop is updating the index value on every loop, this will cause the index to be wrongly aligned by a larger value while the loop shrinks the order.
This may result in inserting and returning a folio of the wrong index and cause data corruption with some userspace workloads [1].
Link https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/ [1] open hereFixes e7a2ab7b3bb5d ("mm: shmem: add mTHP support for anonymous shmem")Signed-off-by Kairui Song <[email protected]>---
Changes from V2:
- Introduce a temporary variable to improve code,
no behavior change, generated code is identical.
- Link to V2: https://lore.kernel.org/linux-mm/[email protected]/Changes from V1:
- Remove unnecessary cleanup and simplify the commit message.
- Link to V1: https://lore.kernel.org/linux-mm/[email protected]/--- mm/shmem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)mm/shmem.c +1
-0@@ -1882,6 +1882,7 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf,struct shmem_inode_info *info =SHMEM_I (inode);unsigned long suitable_orders =0 ;struct folio *folio =NULL ; +pgoff_t aligned_index;long pages;int error, order;@@ -1895,10 +1896,12 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, order =highest_order (suitable_orders);while (suitable_orders) {
mm/shmem.c static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, · line 1904
Quoted 10 lines
mm/shmem.c +5
-3pages =1UL << order; - index =round_down (index, pages); - folio =shmem_alloc_folio (gfp, order, info, index); -if (folio) + aligned_index =round_down (index, pages); + folio =shmem_alloc_folio (gfp, order, info, aligned_index); +if (folio) { + index = aligned_index; goto allocated; + }
Was the found by code inspection or was there a report about this?
Signature · 3 lines
Cheers David / dhildenb
Quoted 42 lines · David Hildenbrand
Quoted 41 lines · Kairui Song
From: Kairui Song <[email protected]>
The order check and fallback loop is updating the index value on every loop, this will cause the index to be wrongly aligned by a larger value while the loop shrinks the order.
This may result in inserting and returning a folio of the wrong index and cause data corruption with some userspace workloads [1].
Link https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/ [1] open hereFixes e7a2ab7b3bb5d ("mm: shmem: add mTHP support for anonymous shmem")Signed-off-by Kairui Song <[email protected]>---
Changes from V2:
- Introduce a temporary variable to improve code,
no behavior change, generated code is identical.
- Link to V2: https://lore.kernel.org/linux-mm/[email protected]/Changes from V1:
- Remove unnecessary cleanup and simplify the commit message.
- Link to V1: https://lore.kernel.org/linux-mm/[email protected]/--- mm/shmem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)mm/shmem.c +1
-0@@ -1882,6 +1882,7 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf,struct shmem_inode_info *info =SHMEM_I (inode);unsigned long suitable_orders =0 ;struct folio *folio =NULL ; +pgoff_t aligned_index;long pages;int error, order;
Quoted 15 lines
mm/shmem.c static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, · line 1904
Quoted 13 lines
mm/shmem.c +5
-3@@ -1895,10 +1896,12 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, order =highest_order (suitable_orders);while (suitable_orders) { pages =1UL << order; - index =round_down (index, pages); - folio =shmem_alloc_folio (gfp, order, info, index); -if (folio) + aligned_index =round_down (index, pages); + folio =shmem_alloc_folio (gfp, order, info, aligned_index); +if (folio) { + index = aligned_index; goto allocated; + }Was the found by code inspection or was there a report about this?
Answering my own question, the "Link:" above should be
Signature · 3 lines
Cheers David / dhildenb
Quoted 60 lines · David Hildenbrand
Quoted 42 lines · David Hildenbrand
Quoted 41 lines · Kairui Song
From: Kairui Song <[email protected]>
The order check and fallback loop is updating the index value on every loop, this will cause the index to be wrongly aligned by a larger value while the loop shrinks the order.
This may result in inserting and returning a folio of the wrong index and cause data corruption with some userspace workloads [1].
Link https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/ [1] open hereFixes e7a2ab7b3bb5d ("mm: shmem: add mTHP support for anonymous shmem")Signed-off-by Kairui Song <[email protected]>---
Changes from V2:
- Introduce a temporary variable to improve code,
no behavior change, generated code is identical.
- Link to V2: https://lore.kernel.org/linux-mm/[email protected]/Changes from V1:
- Remove unnecessary cleanup and simplify the commit message.
- Link to V1: https://lore.kernel.org/linux-mm/[email protected]/--- mm/shmem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)mm/shmem.c +1
-0@@ -1882,6 +1882,7 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf,struct shmem_inode_info *info =SHMEM_I (inode);unsigned long suitable_orders =0 ;struct folio *folio =NULL ; +pgoff_t aligned_index;long pages;int error, order;Quoted 15 lines
mm/shmem.c static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, · line 1904
Quoted 13 lines
mm/shmem.c +5
-3@@ -1895,10 +1896,12 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, order =highest_order (suitable_orders);while (suitable_orders) { pages =1UL << order; - index =round_down (index, pages); - folio =shmem_alloc_folio (gfp, order, info, index); -if (folio) + aligned_index =round_down (index, pages); + folio =shmem_alloc_folio (gfp, order, info, aligned_index); +if (folio) { + index = aligned_index; goto allocated; + }Was the found by code inspection or was there a report about this?
Quoted 5 lines
Answering my own question, the "Link:" above should be
Closes:
https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/
Thanks for the review. It's reported by and fixed by me, so I didn't include an extra Report-By & Closes, I thought that's kind of redundant. Do we need that? Maybe Andrew can help add it :) ?
Barry Song
Reviewed-byQuoted 10 lines
Quoted 6 lines
Answering my own question, the "Link:" above should be
Closes:
https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/Thanks for the review. It's reported by and fixed by me, so I didn't include an extra Report-By & Closes, I thought that's kind of redundant. Do we need that? Maybe Andrew can help add it :) ?
I also think it’s better to use “Closes:”. In that case, we might need to slightly
adjust the commit log to remove "[1]" here.
" This may result in inserting and returning a folio of the wrong index
and cause data corruption with some userspace workloads [1]."
With that,
Thanks
Barry
Quoted 21 lines · Kairui Song
From: Kairui Song <[email protected]>
The order check and fallback loop is updating the index value on every loop, this will cause the index to be wrongly aligned by a larger value while the loop shrinks the order.
This may result in inserting and returning a folio of the wrong index and cause data corruption with some userspace workloads [1].
Link https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/ [1] open hereFixes e7a2ab7b3bb5d ("mm: shmem: add mTHP support for anonymous shmem")Signed-off-by Kairui Song <[email protected]>---
Changes from V2:
- Introduce a temporary variable to improve code,
no behavior change, generated code is identical.
- Link to V2: https://lore.kernel.org/linux-mm/[email protected]/
Quoted 8 lines
Changes from V1:
- Remove unnecessary cleanup and simplify the commit message.
- Link to V1: https://lore.kernel.org/linux-mm/[email protected]/--- mm/shmem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
--
Best Regards,
Yan, Zi
Quoted 9 lines · Kairui Song
From: Kairui Song <[email protected]>
The order check and fallback loop is updating the index value on every loop, this will cause the index to be wrongly aligned by a larger value while the loop shrinks the order.
This may result in inserting and returning a folio of the wrong index and cause data corruption with some userspace workloads [1].
Quoted 6 lines
Link https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/ [1] open hereFixes e7a2ab7b3bb5d ("mm: shmem: add mTHP support for anonymous shmem")Signed-off-by Kairui Song <[email protected]>---
LGTM. Thanks.
Quoted 6 lines · Kairui Song
From: Kairui Song <[email protected]>
The order check and fallback loop is updating the index value on every loop, this will cause the index to be wrongly aligned by a larger value while the loop shrinks the order.
Quoted 7 lines
This may result in inserting and returning a folio of the wrong index and cause data corruption with some userspace workloads [1].
Link https://lore.kernel.org/linux-mm/CAMgjq7DqgAmj25nDUwwu1U2cSGSn8n4-Hqpgottedy0S6YYeUw@mail.gmail.com/ [1] open hereFixes e7a2ab7b3bb5d ("mm: shmem: add mTHP support for anonymous shmem")Signed-off-by Kairui Song <[email protected]>
Yikes... LGTM so:
See below for a small nit.
Quoted 21 lines
---
Changes from V2:
- Introduce a temporary variable to improve code,
no behavior change, generated code is identical.
- Link to V2: https://lore.kernel.org/linux-mm/[email protected]/Changes from V1:
- Remove unnecessary cleanup and simplify the commit message.
- Link to V1: https://lore.kernel.org/linux-mm/[email protected]/--- mm/shmem.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)mm/shmem.c +0
-0
mm/shmem.c static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, · line 1885
Quoted 4 lines
mm/shmem.c +1
-0@@ -1882,6 +1882,7 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf,struct shmem_inode_info *info =SHMEM_I (inode);unsigned long suitable_orders =0 ;struct folio *folio =NULL ; +pgoff_t aligned_index;
Nit, but can't we just declare this in the loop? That makes it even clearer that we don't reuse the value.
Quoted 22 lines
mm/shmem.c +5
-4long pages;int error, order;@@ -1895,10 +1896,12 @@ static struct folio *shmem_alloc_and_add_folio(struct vm_fault *vmf, order =highest_order (suitable_orders);while (suitable_orders) { pages =1UL << order; - index =round_down (index, pages); - folio =shmem_alloc_folio (gfp, order, info, index); -if (folio) + aligned_index =round_down (index, pages); + folio =shmem_alloc_folio (gfp, order, info, aligned_index); +if (folio) { + index = aligned_index; goto allocated; + }if (pages ==HPAGE_PMD_NR )count_vm_event (THP_FILE_FALLBACK ); --2.51.0