Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1576639 > unrolled thread
| Started by | Mel Gorman <mgorman@techsingularity.net> |
|---|---|
| First post | 2017-02-08 16:10 +0100 |
| Last post | 2017-02-08 17:40 +0100 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH] mm, page_alloc: only use per-cpu allocator for irq-safe requests -fix Mel Gorman <mgorman@techsingularity.net> - 2017-02-08 16:10 +0100
Re: [PATCH] mm, page_alloc: only use per-cpu allocator for irq-safe requests -fix Mel Gorman <mgorman@techsingularity.net> - 2017-02-08 17:00 +0100
Re: [PATCH] mm, page_alloc: only use per-cpu allocator for irq-safe requests -fix Thomas Gleixner <tglx@linutronix.de> - 2017-02-08 17:40 +0100
| From | Mel Gorman <mgorman@techsingularity.net> |
|---|---|
| Date | 2017-02-08 16:10 +0100 |
| Subject | [PATCH] mm, page_alloc: only use per-cpu allocator for irq-safe requests -fix |
| Message-ID | <t8C2B-1TA-3@gated-at.bofh.it> |
preempt_enable_no_resched() was used based on review feedback that had no strong objection at the time. It avoided introducing a preemption point where one didn't exist before which was marginal at best. However, it is hazardous to the RT tree according to Thomas Gleixner and is a violation of its expected use according to Peter Zijlstra. In Peter's own words "the only acceptable use of preempt_enable_no_resched() is if the next statement is a schedule() variant". The impact of using preempt_enable in this particular fast path is negligible. This is a fix to the mmotm patch mm-page_alloc-only-use-per-cpu-allocator-for-irq-safe-requests.patch Signed-off-by: Mel Gorman <mgorman@techsingularity.net> --- mm/page_alloc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index eaecb4b145e6..2a36dad03dac 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2520,7 +2520,7 @@ void free_hot_cold_page(struct page *page, bool cold) } out: - preempt_enable_no_resched(); + preempt_enable(); } /* @@ -2686,7 +2686,7 @@ static struct page *rmqueue_pcplist(struct zone *preferred_zone, __count_zid_vm_events(PGALLOC, page_zonenum(page), 1 << order); zone_statistics(preferred_zone, zone); } - preempt_enable_no_resched(); + preempt_enable(); return page; }
[toc] | [next] | [standalone]
| From | Mel Gorman <mgorman@techsingularity.net> |
|---|---|
| Date | 2017-02-08 17:00 +0100 |
| Message-ID | <t8CP0-2b0-13@gated-at.bofh.it> |
| In reply to | #1576639 |
On Wed, Feb 08, 2017 at 03:56:22PM +0100, Thomas Gleixner wrote: > On Wed, 8 Feb 2017, Mel Gorman wrote: > > > preempt_enable_no_resched() was used based on review feedback that had no > > strong objection at the time. It avoided introducing a preemption point > > where one didn't exist before which was marginal at best. > > Actually local_irq_enable() _IS_ a preemption point, indirect but still: > > local_irq_disable() > .... > --> HW interrupt is raised > .... > local_irq_enable() > > handle_irq() > set_need_resched() > ret_from_irq() > preempt() > > while with preempt_disable that looks like this: > > preempt_disable() > .... > --> HW interrupt is raised > handle_irq() > set_need_resched() > ret_from_irq() > .... > preempt_enable() > preempt() > > Now if you use preempt_enable_no_resched() then you miss the preemption and > depending on the actual code path you might run something which takes ages > without hitting a preemption point after that. > Thanks for the education, I had missed it. The changelog should have been "fix a dumb mistake and stick to preempt_enable". Assuming Andrew picks this patch up, it'll be folded into the patch that introduced the problem in the first place and will the broken usage will never hit mainline. > It's not only a problem for RT. It's also in mainline a violation of the > preemption mechanism. > Understood, thanks. -- Mel Gorman SUSE Labs
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2017-02-08 17:40 +0100 |
| Message-ID | <t8CP0-2b0-15@gated-at.bofh.it> |
| In reply to | #1576639 |
On Wed, 8 Feb 2017, Mel Gorman wrote:
> preempt_enable_no_resched() was used based on review feedback that had no
> strong objection at the time. It avoided introducing a preemption point
> where one didn't exist before which was marginal at best.
Actually local_irq_enable() _IS_ a preemption point, indirect but still:
local_irq_disable()
....
--> HW interrupt is raised
....
local_irq_enable()
handle_irq()
set_need_resched()
ret_from_irq()
preempt()
while with preempt_disable that looks like this:
preempt_disable()
....
--> HW interrupt is raised
handle_irq()
set_need_resched()
ret_from_irq()
....
preempt_enable()
preempt()
Now if you use preempt_enable_no_resched() then you miss the preemption and
depending on the actual code path you might run something which takes ages
without hitting a preemption point after that.
It's not only a problem for RT. It's also in mainline a violation of the
preemption mechanism.
Thanks,
tglx
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web