* [Patch] percpu: remove two suspicious break statements @ 2009-11-30 9:12 Amerigo Wang 2009-11-30 11:09 ` Tejun Heo 0 siblings, 1 reply; 13+ messages in thread From: Amerigo Wang @ 2009-11-30 9:12 UTC (permalink / raw) To: linux-kernel; +Cc: Tejun Heo, akpm, Amerigo Wang These two break statements seem to be very suspicious, they are at the end of the statements inside the loop. Remove them. Signed-off-by: WANG Cong <amwang@redhat.com> Cc: Tejun Heo <tj@kernel.org> --- diff --git a/mm/percpu.c b/mm/percpu.c index 5adfc26..dbcfee8 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -917,7 +917,6 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size) pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) { if (rs == page_start && re == page_end) return; - break; } /* immutable chunks can't be depopulated */ @@ -972,7 +971,6 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size) pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end) { if (rs == page_start && re == page_end) goto clear; - break; } /* need to allocate and map pages, this chunk can't be immutable */ ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Patch] percpu: remove two suspicious break statements 2009-11-30 9:12 [Patch] percpu: remove two suspicious break statements Amerigo Wang @ 2009-11-30 11:09 ` Tejun Heo 2009-11-30 19:01 ` Christoph Lameter 0 siblings, 1 reply; 13+ messages in thread From: Tejun Heo @ 2009-11-30 11:09 UTC (permalink / raw) To: Amerigo Wang; +Cc: linux-kernel, akpm On 11/30/2009 06:12 PM, Amerigo Wang wrote: > These two break statements seem to be very suspicious, > they are at the end of the statements inside the loop. > Remove them. > > Signed-off-by: WANG Cong <amwang@redhat.com> > Cc: Tejun Heo <tj@kernel.org> That actually is correct code. It's checking whether the first iteration covers the whole thing. I thought the comment there /* quick path, check whether all pages are already there */ explained it but looking at it again, it definitely isn't enough unless you already know what's going on there. Can you please post a patch to add the comment? Thanks. -- tejun ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch] percpu: remove two suspicious break statements 2009-11-30 11:09 ` Tejun Heo @ 2009-11-30 19:01 ` Christoph Lameter 2009-12-01 0:01 ` [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() Tejun Heo 0 siblings, 1 reply; 13+ messages in thread From: Christoph Lameter @ 2009-11-30 19:01 UTC (permalink / raw) To: Tejun Heo; +Cc: Amerigo Wang, linux-kernel, akpm On Mon, 30 Nov 2009, Tejun Heo wrote: > That actually is correct code. It's checking whether the first > iteration covers the whole thing. I thought the comment there A loop statement that never creates a loop? You either execute a goto or a break. Some more elaborate documentation is needed. ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-11-30 19:01 ` Christoph Lameter @ 2009-12-01 0:01 ` Tejun Heo 2009-12-01 2:02 ` Cong Wang 0 siblings, 1 reply; 13+ messages in thread From: Tejun Heo @ 2009-12-01 0:01 UTC (permalink / raw) To: Christoph Lameter; +Cc: Amerigo Wang, linux-kernel, akpm pcpu_[de]populate_chunk() check whether there's actually any work to do at the beginning and exit early if not. This checking is done by seeing whether the first iteration of pcpu_for_each_[un]pop_region() covers the whole requested region. The resulting code is a bit unusual in that it's loop-like but never loops which apparently confuses people. Add comments to explain it. Signed-off-by: Tejun Heo <tj@kernel.org> Reported-by: Amerigo Wang <amwang@redhat.com> Cc: Christoph Lameter <cl@linux-foundation.org> --- Added to percpu#for-next. This should be clear enough, right? mm/percpu.c | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mm/percpu.c b/mm/percpu.c index 442010c..c264315 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -912,10 +912,15 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size) unsigned long *populated; int rs, re; - /* quick path, check whether it's empty already */ + /* + * Quick path, check whether it's already empty. If the + * region is completely empty, the first iteration will cover + * the whole region. + */ pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) { if (rs == page_start && re == page_end) return; + /* it didn't cover the whole thing, break to slow path */ break; } @@ -967,10 +972,15 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size) unsigned int cpu; int rs, re, rc; - /* quick path, check whether all pages are already there */ + /* + * Quick path, check whether all pages are already there. If + * the region is fully populated, the first iteration will + * cover the whole region. + */ pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end) { if (rs == page_start && re == page_end) goto clear; + /* it didn't cover the whole thing, break to slow path */ break; } -- 1.6.4.2 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-12-01 0:01 ` [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() Tejun Heo @ 2009-12-01 2:02 ` Cong Wang 2009-12-01 5:00 ` Tejun Heo 0 siblings, 1 reply; 13+ messages in thread From: Cong Wang @ 2009-12-01 2:02 UTC (permalink / raw) To: Tejun Heo; +Cc: Christoph Lameter, linux-kernel, akpm Tejun Heo wrote: > pcpu_[de]populate_chunk() check whether there's actually any work to > do at the beginning and exit early if not. This checking is done by > seeing whether the first iteration of pcpu_for_each_[un]pop_region() > covers the whole requested region. The resulting code is a bit > unusual in that it's loop-like but never loops which apparently > confuses people. Add comments to explain it. > > Signed-off-by: Tejun Heo <tj@kernel.org> > Reported-by: Amerigo Wang <amwang@redhat.com> > Cc: Christoph Lameter <cl@linux-foundation.org> > --- > Added to percpu#for-next. This should be clear enough, right? > Nope, comments can never fix bad code. Since these two break statements are intentional, why not use if? Logically, the following two are equalent. for(a1; a2; a3){ if (a4) return; break; } a1; if (a2) { if (a4) return; } And the latter is much more readable than the former. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-12-01 2:02 ` Cong Wang @ 2009-12-01 5:00 ` Tejun Heo 2009-12-01 5:09 ` Tejun Heo 0 siblings, 1 reply; 13+ messages in thread From: Tejun Heo @ 2009-12-01 5:00 UTC (permalink / raw) To: Cong Wang; +Cc: Christoph Lameter, linux-kernel, akpm Hello, On 12/01/2009 11:02 AM, Cong Wang wrote: > Nope, comments can never fix bad code. > > Since these two break statements are intentional, why not use if? > Logically, the following two are equalent. > > for(a1; a2; a3){ > if (a4) > return; > break; > } > > > a1; > if (a2) { > if (a4) > return; > } > > And the latter is much more readable than the former. I thought about that but didn't want to open code the special and fairly complex loop construct used there. To me, it seemed using the same loop construct would be much less error-prone than open coding the loop mostly because those two special cases are the only place where that is necessary. Maybe we can add pcpu_first_[un]pop_region() macros and use them there but is the first iteration check that bad even with sufficient explanations? Thanks. -- tejun ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-12-01 5:00 ` Tejun Heo @ 2009-12-01 5:09 ` Tejun Heo 2009-12-01 5:40 ` Cong Wang 0 siblings, 1 reply; 13+ messages in thread From: Tejun Heo @ 2009-12-01 5:09 UTC (permalink / raw) To: Cong Wang; +Cc: Christoph Lameter, linux-kernel, akpm On 12/01/2009 02:00 PM, Tejun Heo wrote: > I thought about that but didn't want to open code the special and > fairly complex loop construct used there. To me, it seemed using the > same loop construct would be much less error-prone than open coding > the loop mostly because those two special cases are the only place > where that is necessary. Maybe we can add pcpu_first_[un]pop_region() > macros and use them there but is the first iteration check that bad > even with sufficient explanations? So, something like the following. #define pcpu_first_unpop_region(chunk, rs, re, start, end) do { \ (rs) = (start); \ pcpu_next_unpop((chunk), &(rs), &(re), (end)); \ } while (0) #define pcpu_for_each_unpop_region(chunk, rs, re, start, end) \ for (pcpu_first_unpop_region(chunk, rs, re, start, end); \ (rs) < (re); \ (rs) = (re) + 1, pcpu_next_unpop((chunk), &(rs), &(re), (end))) #define pcpu_first_pop_region(chunk, rs, re, start, end) do { \ (rs) = (start); \ pcpu_next_pop((chunk), &(rs), &(re), (end)); \ } while (0) #define pcpu_for_each_pop_region(chunk, rs, re, start, end) \ for (pcpu_first_pop_region(chunk, rs, re, start, end); \ (rs) < (re); \ (rs) = (re) + 1, pcpu_next_pop((chunk), &(rs), &(re), (end))) It might be better to make these proper functions which take pointers but that makes the only two interfaces for region iterators disagree about how they take parameters. So, I don't know. The first iteration only loop looks a bit unusual for sure but it isn't something conceptually convoluted. Thanks. -- tejun ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-12-01 5:09 ` Tejun Heo @ 2009-12-01 5:40 ` Cong Wang 2009-12-01 5:47 ` Tejun Heo 0 siblings, 1 reply; 13+ messages in thread From: Cong Wang @ 2009-12-01 5:40 UTC (permalink / raw) To: Tejun Heo; +Cc: Christoph Lameter, linux-kernel, akpm Tejun Heo wrote: > On 12/01/2009 02:00 PM, Tejun Heo wrote: >> I thought about that but didn't want to open code the special and >> fairly complex loop construct used there. To me, it seemed using the >> same loop construct would be much less error-prone than open coding >> the loop mostly because those two special cases are the only place >> where that is necessary. Maybe we can add pcpu_first_[un]pop_region() >> macros and use them there but is the first iteration check that bad >> even with sufficient explanations? > > So, something like the following. Thanks for working on this. > > #define pcpu_first_unpop_region(chunk, rs, re, start, end) do { \ > (rs) = (start); \ > pcpu_next_unpop((chunk), &(rs), &(re), (end)); \ > } while (0) > > #define pcpu_for_each_unpop_region(chunk, rs, re, start, end) \ > for (pcpu_first_unpop_region(chunk, rs, re, start, end); \ > (rs) < (re); \ > (rs) = (re) + 1, pcpu_next_unpop((chunk), &(rs), &(re), (end))) > > #define pcpu_first_pop_region(chunk, rs, re, start, end) do { \ > (rs) = (start); \ > pcpu_next_pop((chunk), &(rs), &(re), (end)); \ > } while (0) > > #define pcpu_for_each_pop_region(chunk, rs, re, start, end) \ > for (pcpu_first_pop_region(chunk, rs, re, start, end); \ > (rs) < (re); \ > (rs) = (re) + 1, pcpu_next_pop((chunk), &(rs), &(re), (end))) > > It might be better to make these proper functions which take pointers > but that makes the only two interfaces for region iterators disagree > about how they take parameters. > > So, I don't know. The first iteration only loop looks a bit unusual > for sure but it isn't something conceptually convoluted. Now this seems to be better. So with this change, we can do: pcpu_first_pop_region(chunk, rs, re, start, end); if (rs < re && ...) return; Right? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-12-01 5:40 ` Cong Wang @ 2009-12-01 5:47 ` Tejun Heo 2009-12-01 6:35 ` Cong Wang 0 siblings, 1 reply; 13+ messages in thread From: Tejun Heo @ 2009-12-01 5:47 UTC (permalink / raw) To: Cong Wang; +Cc: Christoph Lameter, linux-kernel, akpm Hello, On 12/01/2009 02:40 PM, Cong Wang wrote: >> So, I don't know. The first iteration only loop looks a bit unusual >> for sure but it isn't something conceptually convoluted. > > Now this seems to be better. So with this change, we can do: > > pcpu_first_pop_region(chunk, rs, re, start, end); > if (rs < re && ...) > return; > > Right? Yeap, but is that any better? Passing lvalue loop parameters to loop constructs is customary. For almost all other cases, it's not, so pcpu_first_pop_region(chunk, &rs, &re, start, end) would be better but then we have two similar looking interfaces which take different types of parameters. Also, you probably can drop rs < re test there but for me it just seems easier to simply check the first iteration. If you think it's something worth changing and it looks better afterwards, please send a patch. Thanks. -- tejun ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-12-01 5:47 ` Tejun Heo @ 2009-12-01 6:35 ` Cong Wang 2009-12-01 6:59 ` Tejun Heo 0 siblings, 1 reply; 13+ messages in thread From: Cong Wang @ 2009-12-01 6:35 UTC (permalink / raw) To: Tejun Heo; +Cc: Christoph Lameter, linux-kernel, akpm [-- Attachment #1: Type: text/plain, Size: 1025 bytes --] Tejun Heo wrote: > Hello, > > On 12/01/2009 02:40 PM, Cong Wang wrote: >>> So, I don't know. The first iteration only loop looks a bit unusual >>> for sure but it isn't something conceptually convoluted. >> Now this seems to be better. So with this change, we can do: >> >> pcpu_first_pop_region(chunk, rs, re, start, end); >> if (rs < re && ...) >> return; >> >> Right? > > Yeap, but is that any better? Passing lvalue loop parameters to loop > constructs is customary. For almost all other cases, it's not, so > > pcpu_first_pop_region(chunk, &rs, &re, start, end) > > would be better but then we have two similar looking interfaces which > take different types of parameters. Also, you probably can drop rs < > re test there but for me it just seems easier to simply check the > first iteration. If you think it's something worth changing and it > looks better afterwards, please send a patch. > What do you think about the patch below? Untested. ----------- Signed-off-by: WANG Cong <amwang@redhat.com> [-- Attachment #2: mm-percpu_c-remove-two-useless-break.diff --] [-- Type: text/plain, Size: 1326 bytes --] diff --git a/mm/percpu.c b/mm/percpu.c index 5adfc26..d1da616 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -911,14 +911,12 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size) int page_end = PFN_UP(off + size); struct page **pages; unsigned long *populated; - int rs, re; + int rs = page_start, re; /* quick path, check whether it's empty already */ - pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) { - if (rs == page_start && re == page_end) - return; - break; - } + pcpu_next_unpop(chunk, &rs, &re, page_end); + if (rs == page_start && re == page_end) + return; /* immutable chunks can't be depopulated */ WARN_ON(chunk->immutable); @@ -966,14 +964,12 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size) struct page **pages; unsigned long *populated; unsigned int cpu; - int rs, re, rc; + int rs = page_start, re, rc; /* quick path, check whether all pages are already there */ - pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end) { - if (rs == page_start && re == page_end) - goto clear; - break; - } + pcpu_next_pop(chunk, &rs, &re, page_end); + if (rs == page_start && re == page_end) + goto clear; /* need to allocate and map pages, this chunk can't be immutable */ WARN_ON(chunk->immutable); ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() 2009-12-01 6:35 ` Cong Wang @ 2009-12-01 6:59 ` Tejun Heo 2009-12-01 7:13 ` [PATCH] percpu: refactor the code " Cong Wang 0 siblings, 1 reply; 13+ messages in thread From: Tejun Heo @ 2009-12-01 6:59 UTC (permalink / raw) To: Cong Wang; +Cc: Christoph Lameter, linux-kernel, akpm On 12/01/2009 03:35 PM, Cong Wang wrote: > What do you think about the patch below? Untested. Oh, yeah, that's prettier. Just one thing, can you please move rs initialization right above the pcpu_next_[un]pop() call? The input/output parameters for those functions are already pretty confusing, let's make it at least a bit clearer. Thanks. -- tejun ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] percpu: refactor the code in pcpu_[de]populate_chunk() 2009-12-01 6:59 ` Tejun Heo @ 2009-12-01 7:13 ` Cong Wang 2009-12-01 14:31 ` Tejun Heo 0 siblings, 1 reply; 13+ messages in thread From: Cong Wang @ 2009-12-01 7:13 UTC (permalink / raw) To: Tejun Heo; +Cc: Christoph Lameter, linux-kernel, akpm [-- Attachment #1: Type: text/plain, Size: 551 bytes --] Tejun Heo wrote: > On 12/01/2009 03:35 PM, Cong Wang wrote: >> What do you think about the patch below? Untested. > > Oh, yeah, that's prettier. Just one thing, can you please move rs > initialization right above the pcpu_next_[un]pop() call? The > input/output parameters for those functions are already pretty > confusing, let's make it at least a bit clearer. > Sure, done. -------------> Using break statement at the end of a for loop is confusing, refactor it by replacing the for loop. Signed-off-by: WANG Cong <amwang@redhat.com> --- [-- Attachment #2: mm-percpu_c-remove-two-useless-break.diff --] [-- Type: text/plain, Size: 1147 bytes --] diff --git a/mm/percpu.c b/mm/percpu.c index 5adfc26..2941ed9 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -914,11 +914,10 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size) int rs, re; /* quick path, check whether it's empty already */ - pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) { - if (rs == page_start && re == page_end) - return; - break; - } + rs = page_start; + pcpu_next_unpop(chunk, &rs, &re, page_end); + if (rs == page_start && re == page_end) + return; /* immutable chunks can't be depopulated */ WARN_ON(chunk->immutable); @@ -969,11 +968,10 @@ static int pcpu_populate_chunk(struct pcpu_chunk *chunk, int off, int size) int rs, re, rc; /* quick path, check whether all pages are already there */ - pcpu_for_each_pop_region(chunk, rs, re, page_start, page_end) { - if (rs == page_start && re == page_end) - goto clear; - break; - } + rs = page_start; + pcpu_next_pop(chunk, &rs, &re, page_end); + if (rs == page_start && re == page_end) + goto clear; /* need to allocate and map pages, this chunk can't be immutable */ WARN_ON(chunk->immutable); ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] percpu: refactor the code in pcpu_[de]populate_chunk() 2009-12-01 7:13 ` [PATCH] percpu: refactor the code " Cong Wang @ 2009-12-01 14:31 ` Tejun Heo 0 siblings, 0 replies; 13+ messages in thread From: Tejun Heo @ 2009-12-01 14:31 UTC (permalink / raw) To: Cong Wang; +Cc: Christoph Lameter, linux-kernel, akpm On 12/01/2009 04:13 PM, Cong Wang wrote: > Using break statement at the end of a for loop is confusing, > refactor it by replacing the for loop. > > Signed-off-by: WANG Cong <amwang@redhat.com> Applied to percpu#for-next. Thanks. -- tejun ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-12-01 14:32 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-11-30 9:12 [Patch] percpu: remove two suspicious break statements Amerigo Wang 2009-11-30 11:09 ` Tejun Heo 2009-11-30 19:01 ` Christoph Lameter 2009-12-01 0:01 ` [PATCH] percpu: explain quick paths in pcpu_[de]populate_chunk() Tejun Heo 2009-12-01 2:02 ` Cong Wang 2009-12-01 5:00 ` Tejun Heo 2009-12-01 5:09 ` Tejun Heo 2009-12-01 5:40 ` Cong Wang 2009-12-01 5:47 ` Tejun Heo 2009-12-01 6:35 ` Cong Wang 2009-12-01 6:59 ` Tejun Heo 2009-12-01 7:13 ` [PATCH] percpu: refactor the code " Cong Wang 2009-12-01 14:31 ` Tejun Heo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox