Message ID | 20240924123954.18933-5-richard.weiyang@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | cleanup maple_alloc related functions | expand |
Related fix has been posted, but not merged yet. lkml.kernel.org/r/20240626160631.3636515-1-Liam.Howlett@oracle.com May drop this one. On Tue, Sep 24, 2024 at 12:39:54PM +0000, Wei Yang wrote: >We got an rare case when mas_node_count() would fail even there is >enough memory. > >The reason is the maple_alloc grows downward. And when hit a full >maple_alloc, the max_req would be 0. This leads to mt_alloc_bulk() >return 0, which means failure here. > >For example, here is the test code: > > expect = MAPLE_ALLOC_SLOTS + 1; > mas_node_count(&ms, expect); > pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); > expect = MAPLE_ALLOC_SLOTS * 2 + 2; > mas_node_count(&ms, expect); > pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); > >We will get the following output, which shows we fail to allocate the >required number of nodes. > > expect 31 allocated 31 > expect 62 allocated 61 > >The straight forward way to fix it is go down one level more. > >Signed-off-by: Wei Yang <richard.weiyang@gmail.com> >CC: Liam R. Howlett <Liam.Howlett@Oracle.com> >CC: Sidhartha Kumar <sidhartha.kumar@oracle.com> >--- > lib/maple_tree.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/lib/maple_tree.c b/lib/maple_tree.c >index 1cbc5f7ca40d..dd33d0793dd1 100644 >--- a/lib/maple_tree.c >+++ b/lib/maple_tree.c >@@ -1253,8 +1253,10 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) > } > > node = mas->alloc; >- while (requested) { >+ for (; requested; node = node->slot[0]) { > max_req = MAPLE_ALLOC_SLOTS - node->node_count; >+ if (unlikely(!max_req)) >+ continue; > slots = (void **)&node->slot[node->node_count]; > max_req = min(requested, max_req); > count = mt_alloc_bulk(gfp, max_req, slots); >@@ -1268,7 +1270,6 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) > > node->node_count += count; > allocated += count; >- node = node->slot[0]; > requested -= count; > } > mas->alloc->total = allocated; >-- >2.34.1
* Wei Yang <richard.weiyang@gmail.com> [241010 21:27]: > > Related fix has been posted, but not merged yet. > > lkml.kernel.org/r/20240626160631.3636515-1-Liam.Howlett@oracle.com > > May drop this one. Yes, I thought we had fixed this already. > > On Tue, Sep 24, 2024 at 12:39:54PM +0000, Wei Yang wrote: > >We got an rare case when mas_node_count() would fail even there is > >enough memory. > > > >The reason is the maple_alloc grows downward. And when hit a full > >maple_alloc, the max_req would be 0. This leads to mt_alloc_bulk() > >return 0, which means failure here. > > > >For example, here is the test code: > > > > expect = MAPLE_ALLOC_SLOTS + 1; > > mas_node_count(&ms, expect); > > pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); > > expect = MAPLE_ALLOC_SLOTS * 2 + 2; > > mas_node_count(&ms, expect); > > pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); > > > >We will get the following output, which shows we fail to allocate the > >required number of nodes. > > > > expect 31 allocated 31 > > expect 62 allocated 61 > > > >The straight forward way to fix it is go down one level more. > > > >Signed-off-by: Wei Yang <richard.weiyang@gmail.com> > >CC: Liam R. Howlett <Liam.Howlett@Oracle.com> > >CC: Sidhartha Kumar <sidhartha.kumar@oracle.com> > >--- > > lib/maple_tree.c | 5 +++-- > > 1 file changed, 3 insertions(+), 2 deletions(-) > > > >diff --git a/lib/maple_tree.c b/lib/maple_tree.c > >index 1cbc5f7ca40d..dd33d0793dd1 100644 > >--- a/lib/maple_tree.c > >+++ b/lib/maple_tree.c > >@@ -1253,8 +1253,10 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) > > } > > > > node = mas->alloc; > >- while (requested) { > >+ for (; requested; node = node->slot[0]) { > > max_req = MAPLE_ALLOC_SLOTS - node->node_count; > >+ if (unlikely(!max_req)) > >+ continue; > > slots = (void **)&node->slot[node->node_count]; > > max_req = min(requested, max_req); > > count = mt_alloc_bulk(gfp, max_req, slots); > >@@ -1268,7 +1270,6 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) > > > > node->node_count += count; > > allocated += count; > >- node = node->slot[0]; > > requested -= count; > > } > > mas->alloc->total = allocated; > >-- > >2.34.1 > > -- > Wei Yang > Help you, Help me >
* Wei Yang <richard.weiyang@gmail.com> [241010 21:27]: > > Related fix has been posted, but not merged yet. > > lkml.kernel.org/r/20240626160631.3636515-1-Liam.Howlett@oracle.com > > May drop this one. Yes, thanks. This can be dropped in favour of the other commit. > > On Tue, Sep 24, 2024 at 12:39:54PM +0000, Wei Yang wrote: > >We got an rare case when mas_node_count() would fail even there is > >enough memory. > > > >The reason is the maple_alloc grows downward. And when hit a full > >maple_alloc, the max_req would be 0. This leads to mt_alloc_bulk() > >return 0, which means failure here. > > > >For example, here is the test code: > > > > expect = MAPLE_ALLOC_SLOTS + 1; > > mas_node_count(&ms, expect); > > pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); > > expect = MAPLE_ALLOC_SLOTS * 2 + 2; > > mas_node_count(&ms, expect); > > pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); > > > >We will get the following output, which shows we fail to allocate the > >required number of nodes. > > > > expect 31 allocated 31 > > expect 62 allocated 61 > > > >The straight forward way to fix it is go down one level more. > > > >Signed-off-by: Wei Yang <richard.weiyang@gmail.com> > >CC: Liam R. Howlett <Liam.Howlett@Oracle.com> > >CC: Sidhartha Kumar <sidhartha.kumar@oracle.com> > >--- > > lib/maple_tree.c | 5 +++-- > > 1 file changed, 3 insertions(+), 2 deletions(-) > > > >diff --git a/lib/maple_tree.c b/lib/maple_tree.c > >index 1cbc5f7ca40d..dd33d0793dd1 100644 > >--- a/lib/maple_tree.c > >+++ b/lib/maple_tree.c > >@@ -1253,8 +1253,10 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) > > } > > > > node = mas->alloc; > >- while (requested) { > >+ for (; requested; node = node->slot[0]) { > > max_req = MAPLE_ALLOC_SLOTS - node->node_count; > >+ if (unlikely(!max_req)) > >+ continue; > > slots = (void **)&node->slot[node->node_count]; > > max_req = min(requested, max_req); > > count = mt_alloc_bulk(gfp, max_req, slots); > >@@ -1268,7 +1270,6 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) > > > > node->node_count += count; > > allocated += count; > >- node = node->slot[0]; > > requested -= count; > > } > > mas->alloc->total = allocated; > >-- > >2.34.1 > > -- > Wei Yang > Help you, Help me >
diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 1cbc5f7ca40d..dd33d0793dd1 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -1253,8 +1253,10 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) } node = mas->alloc; - while (requested) { + for (; requested; node = node->slot[0]) { max_req = MAPLE_ALLOC_SLOTS - node->node_count; + if (unlikely(!max_req)) + continue; slots = (void **)&node->slot[node->node_count]; max_req = min(requested, max_req); count = mt_alloc_bulk(gfp, max_req, slots); @@ -1268,7 +1270,6 @@ static inline void mas_alloc_nodes(struct ma_state *mas, gfp_t gfp) node->node_count += count; allocated += count; - node = node->slot[0]; requested -= count; } mas->alloc->total = allocated;
We got an rare case when mas_node_count() would fail even there is enough memory. The reason is the maple_alloc grows downward. And when hit a full maple_alloc, the max_req would be 0. This leads to mt_alloc_bulk() return 0, which means failure here. For example, here is the test code: expect = MAPLE_ALLOC_SLOTS + 1; mas_node_count(&ms, expect); pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); expect = MAPLE_ALLOC_SLOTS * 2 + 2; mas_node_count(&ms, expect); pr_info("expect %d allocated %lu\n", expect, mas_allocated(&ms)); We will get the following output, which shows we fail to allocate the required number of nodes. expect 31 allocated 31 expect 62 allocated 61 The straight forward way to fix it is go down one level more. Signed-off-by: Wei Yang <richard.weiyang@gmail.com> CC: Liam R. Howlett <Liam.Howlett@Oracle.com> CC: Sidhartha Kumar <sidhartha.kumar@oracle.com> --- lib/maple_tree.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)