]>
Commit | Line | Data |
---|---|---|
d354e29e FG |
1 | From 3168fc7faf603da9d523c9dffbec6fee5b1a8a04 Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com> | |
3 | Date: Wed, 4 Jan 2017 11:29:00 +0100 | |
4 | Subject: [PATCH 1/2] Revert "mm: throttle on IO only when there are too many | |
5 | dirty and writeback pages" | |
6 | MIME-Version: 1.0 | |
7 | Content-Type: text/plain; charset=UTF-8 | |
8 | Content-Transfer-Encoding: 8bit | |
9 | ||
10 | This reverts commit 57e9ef475661f46769cad6c0ed9a13f0cec1dbd8. | |
11 | ||
12 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
13 | --- | |
14 | mm/backing-dev.c | 20 +++++++++++++++++--- | |
15 | mm/page_alloc.c | 41 ++++------------------------------------- | |
16 | 2 files changed, 21 insertions(+), 40 deletions(-) | |
17 | ||
18 | diff --git a/mm/backing-dev.c b/mm/backing-dev.c | |
19 | index a1aef87..9ef80bf 100644 | |
20 | --- a/mm/backing-dev.c | |
21 | +++ b/mm/backing-dev.c | |
22 | @@ -976,8 +976,9 @@ EXPORT_SYMBOL(congestion_wait); | |
23 | * jiffies for either a BDI to exit congestion of the given @sync queue | |
24 | * or a write to complete. | |
25 | * | |
26 | - * In the absence of zone congestion, cond_resched() is called to yield | |
27 | - * the processor if necessary but otherwise does not sleep. | |
28 | + * In the absence of zone congestion, a short sleep or a cond_resched is | |
29 | + * performed to yield the processor and to allow other subsystems to make | |
30 | + * a forward progress. | |
31 | * | |
32 | * The return value is 0 if the sleep is for the full timeout. Otherwise, | |
33 | * it is the number of jiffies that were still remaining when the function | |
34 | @@ -997,7 +998,20 @@ long wait_iff_congested(struct zone *zone, int sync, long timeout) | |
35 | */ | |
36 | if (atomic_read(&nr_wb_congested[sync]) == 0 || | |
37 | !test_bit(ZONE_CONGESTED, &zone->flags)) { | |
38 | - cond_resched(); | |
39 | + | |
40 | + /* | |
41 | + * Memory allocation/reclaim might be called from a WQ | |
42 | + * context and the current implementation of the WQ | |
43 | + * concurrency control doesn't recognize that a particular | |
44 | + * WQ is congested if the worker thread is looping without | |
45 | + * ever sleeping. Therefore we have to do a short sleep | |
46 | + * here rather than calling cond_resched(). | |
47 | + */ | |
48 | + if (current->flags & PF_WQ_WORKER) | |
49 | + schedule_timeout_uninterruptible(1); | |
50 | + else | |
51 | + cond_resched(); | |
52 | + | |
53 | /* In case we scheduled, work out time remaining */ | |
54 | ret = timeout - (jiffies - start); | |
55 | if (ret < 0) | |
56 | diff --git a/mm/page_alloc.c b/mm/page_alloc.c | |
57 | index aadbd7e..f13b503 100644 | |
58 | --- a/mm/page_alloc.c | |
59 | +++ b/mm/page_alloc.c | |
60 | @@ -3038,9 +3038,8 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order, | |
61 | for_each_zone_zonelist_nodemask(zone, z, ac->zonelist, ac->high_zoneidx, | |
62 | ac->nodemask) { | |
63 | unsigned long available; | |
64 | - unsigned long reclaimable; | |
65 | ||
66 | - available = reclaimable = zone_reclaimable_pages(zone); | |
67 | + available = zone_reclaimable_pages(zone); | |
68 | available -= DIV_ROUND_UP(no_progress_loops * available, | |
69 | MAX_RECLAIM_RETRIES); | |
70 | available += zone_page_state_snapshot(zone, NR_FREE_PAGES); | |
71 | @@ -3050,41 +3049,9 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order, | |
72 | * available? | |
73 | */ | |
74 | if (__zone_watermark_ok(zone, order, min_wmark_pages(zone), | |
75 | - ac->classzone_idx, alloc_flags, available)) { | |
76 | - /* | |
77 | - * If we didn't make any progress and have a lot of | |
78 | - * dirty + writeback pages then we should wait for | |
79 | - * an IO to complete to slow down the reclaim and | |
80 | - * prevent from pre mature OOM | |
81 | - */ | |
82 | - if (!did_some_progress) { | |
83 | - unsigned long writeback; | |
84 | - unsigned long dirty; | |
85 | - | |
86 | - writeback = zone_page_state_snapshot(zone, | |
87 | - NR_WRITEBACK); | |
88 | - dirty = zone_page_state_snapshot(zone, NR_FILE_DIRTY); | |
89 | - | |
90 | - if (2*(writeback + dirty) > reclaimable) { | |
91 | - congestion_wait(BLK_RW_ASYNC, HZ/10); | |
92 | - return true; | |
93 | - } | |
94 | - } | |
95 | - | |
96 | - /* | |
97 | - * Memory allocation/reclaim might be called from a WQ | |
98 | - * context and the current implementation of the WQ | |
99 | - * concurrency control doesn't recognize that | |
100 | - * a particular WQ is congested if the worker thread is | |
101 | - * looping without ever sleeping. Therefore we have to | |
102 | - * do a short sleep here rather than calling | |
103 | - * cond_resched(). | |
104 | - */ | |
105 | - if (current->flags & PF_WQ_WORKER) | |
106 | - schedule_timeout_uninterruptible(1); | |
107 | - else | |
108 | - cond_resched(); | |
109 | - | |
110 | + ac->high_zoneidx, alloc_flags, available)) { | |
111 | + /* Wait for some write requests to complete then retry */ | |
112 | + wait_iff_congested(zone, BLK_RW_ASYNC, HZ/50); | |
113 | return true; | |
114 | } | |
115 | } | |
116 | -- | |
117 | 2.1.4 | |
118 |