Skip to content

Commit ec3dcef

Browse files
authored
Merge pull request #2 from Rasenkai/6.5/cachy
6.5: mm patches
2 parents b78b395 + 132f9fd commit ec3dcef

File tree

6 files changed

+55
-37
lines changed

6 files changed

+55
-37
lines changed

lib/scatterlist.c

+2-21
Original file line numberDiff line numberDiff line change
@@ -150,31 +150,12 @@ EXPORT_SYMBOL(sg_init_one);
150150
*/
151151
static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask)
152152
{
153-
if (nents == SG_MAX_SINGLE_ALLOC) {
154-
/*
155-
* Kmemleak doesn't track page allocations as they are not
156-
* commonly used (in a raw form) for kernel data structures.
157-
* As we chain together a list of pages and then a normal
158-
* kmalloc (tracked by kmemleak), in order to for that last
159-
* allocation not to become decoupled (and thus a
160-
* false-positive) we need to inform kmemleak of all the
161-
* intermediate allocations.
162-
*/
163-
void *ptr = (void *) __get_free_page(gfp_mask);
164-
kmemleak_alloc(ptr, PAGE_SIZE, 1, gfp_mask);
165-
return ptr;
166-
} else
167-
return kmalloc_array(nents, sizeof(struct scatterlist),
168-
gfp_mask);
153+
return kmalloc_array(nents, sizeof(struct scatterlist), gfp_mask);
169154
}
170155

171156
static void sg_kfree(struct scatterlist *sg, unsigned int nents)
172157
{
173-
if (nents == SG_MAX_SINGLE_ALLOC) {
174-
kmemleak_free(sg);
175-
free_page((unsigned long) sg);
176-
} else
177-
kfree(sg);
158+
kfree(sg);
178159
}
179160

180161
/**

mm/compaction.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1780,7 +1780,7 @@ static int sysctl_compact_unevictable_allowed __read_mostly = CONFIG_COMPACT_UNE
17801780
* aggressively the kernel should compact memory in the
17811781
* background. It takes values in the range [0, 100].
17821782
*/
1783-
static unsigned int __read_mostly sysctl_compaction_proactiveness = 20;
1783+
static unsigned int __read_mostly sysctl_compaction_proactiveness;
17841784
static int sysctl_extfrag_threshold = 500;
17851785
static int __read_mostly sysctl_compact_memory;
17861786

mm/internal.h

+1
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ extern void prep_compound_page(struct page *page, unsigned int order);
421421
extern void post_alloc_hook(struct page *page, unsigned int order,
422422
gfp_t gfp_flags);
423423
extern int user_min_free_kbytes;
424+
extern atomic_long_t kswapd_waiters;
424425

425426
extern void free_unref_page(struct page *page, unsigned int order);
426427
extern void free_unref_page_list(struct list_head *list);

mm/list_lru.c

+4
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ EXPORT_SYMBOL_GPL(list_lru_isolate_move);
178178
unsigned long list_lru_count_one(struct list_lru *lru,
179179
int nid, struct mem_cgroup *memcg)
180180
{
181+
#if defined(CONFIG_MEMCG) && !defined(CONFIG_SLOB)
181182
struct list_lru_one *l;
182183
long count;
183184

@@ -190,6 +191,9 @@ unsigned long list_lru_count_one(struct list_lru *lru,
190191
count = 0;
191192

192193
return count;
194+
#else
195+
return READ_ONCE(lru->node[nid].lru.nr_items);
196+
#endif
193197
}
194198
EXPORT_SYMBOL_GPL(list_lru_count_one);
195199

mm/page_alloc.c

+33-9
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ EXPORT_SYMBOL(node_states);
204204

205205
gfp_t gfp_allowed_mask __read_mostly = GFP_BOOT_MASK;
206206

207+
atomic_long_t kswapd_waiters = ATOMIC_LONG_INIT(0);
208+
207209
/*
208210
* A cached value of the page's pageblock's migratetype, used when the page is
209211
* put on a pcplist. Used to avoid the pageblock migratetype lookup when
@@ -297,7 +299,7 @@ static compound_page_dtor * const compound_page_dtors[NR_COMPOUND_DTORS] = {
297299

298300
int min_free_kbytes = 1024;
299301
int user_min_free_kbytes = -1;
300-
static int watermark_boost_factor __read_mostly = 15000;
302+
static int watermark_boost_factor __read_mostly;
301303
static int watermark_scale_factor = 10;
302304

303305
/* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */
@@ -2152,16 +2154,17 @@ __rmqueue(struct zone *zone, unsigned int order, int migratetype,
21522154
}
21532155

21542156
/*
2155-
* Obtain a specified number of elements from the buddy allocator, all under
2156-
* a single hold of the lock, for efficiency. Add them to the supplied list.
2157-
* Returns the number of new pages which were placed at *list.
2157+
* Obtain a specified number of elements from the buddy allocator, and relax the
2158+
* zone lock when needed. Add them to the supplied list. Returns the number of
2159+
* new pages which were placed at *list.
21582160
*/
21592161
static int rmqueue_bulk(struct zone *zone, unsigned int order,
21602162
unsigned long count, struct list_head *list,
21612163
int migratetype, unsigned int alloc_flags)
21622164
{
2165+
const bool can_resched = !preempt_count() && !irqs_disabled();
21632166
unsigned long flags;
2164-
int i;
2167+
int i, last_mod = 0;
21652168

21662169
spin_lock_irqsave(&zone->lock, flags);
21672170
for (i = 0; i < count; ++i) {
@@ -2170,6 +2173,18 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
21702173
if (unlikely(page == NULL))
21712174
break;
21722175

2176+
/* Reschedule and ease the contention on the lock if needed */
2177+
if (i + 1 < count && ((can_resched && need_resched()) ||
2178+
spin_needbreak(&zone->lock))) {
2179+
__mod_zone_page_state(zone, NR_FREE_PAGES,
2180+
-((i + 1 - last_mod) << order));
2181+
last_mod = i + 1;
2182+
spin_unlock_irqrestore(&zone->lock, flags);
2183+
if (can_resched)
2184+
cond_resched();
2185+
spin_lock_irqsave(&zone->lock, flags);
2186+
}
2187+
21732188
/*
21742189
* Split buddy pages returned by expand() are received here in
21752190
* physical page order. The page is added to the tail of
@@ -2186,7 +2201,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
21862201
-(1 << order));
21872202
}
21882203

2189-
__mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
2204+
__mod_zone_page_state(zone, NR_FREE_PAGES, -((i - last_mod) << order));
21902205
spin_unlock_irqrestore(&zone->lock, flags);
21912206

21922207
return i;
@@ -3962,6 +3977,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
39623977
unsigned int cpuset_mems_cookie;
39633978
unsigned int zonelist_iter_cookie;
39643979
int reserve_flags;
3980+
bool woke_kswapd = false;
39653981

39663982
restart:
39673983
compaction_retries = 0;
@@ -4001,8 +4017,13 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
40014017
goto nopage;
40024018
}
40034019

4004-
if (alloc_flags & ALLOC_KSWAPD)
4020+
if (alloc_flags & ALLOC_KSWAPD) {
4021+
if (!woke_kswapd) {
4022+
atomic_long_inc(&kswapd_waiters);
4023+
woke_kswapd = true;
4024+
}
40054025
wake_all_kswapds(order, gfp_mask, ac);
4026+
}
40064027

40074028
/*
40084029
* The adjusted alloc_flags might result in immediate success, so try
@@ -4217,9 +4238,12 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
42174238
goto retry;
42184239
}
42194240
fail:
4220-
warn_alloc(gfp_mask, ac->nodemask,
4221-
"page allocation failure: order:%u", order);
42224241
got_pg:
4242+
if (woke_kswapd)
4243+
atomic_long_dec(&kswapd_waiters);
4244+
if (!page)
4245+
warn_alloc(gfp_mask, ac->nodemask,
4246+
"page allocation failure: order:%u", order);
42234247
return page;
42244248
}
42254249

mm/vmscan.c

+14-6
Original file line numberDiff line numberDiff line change
@@ -6901,7 +6901,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
69016901
return 0;
69026902
}
69036903

6904-
static bool allow_direct_reclaim(pg_data_t *pgdat)
6904+
static bool allow_direct_reclaim(pg_data_t *pgdat, bool using_kswapd)
69056905
{
69066906
struct zone *zone;
69076907
unsigned long pfmemalloc_reserve = 0;
@@ -6930,6 +6930,10 @@ static bool allow_direct_reclaim(pg_data_t *pgdat)
69306930

69316931
wmark_ok = free_pages > pfmemalloc_reserve / 2;
69326932

6933+
/* The throttled direct reclaimer is now a kswapd waiter */
6934+
if (unlikely(!using_kswapd && !wmark_ok))
6935+
atomic_long_inc(&kswapd_waiters);
6936+
69336937
/* kswapd must be awake if processes are being throttled */
69346938
if (!wmark_ok && waitqueue_active(&pgdat->kswapd_wait)) {
69356939
if (READ_ONCE(pgdat->kswapd_highest_zoneidx) > ZONE_NORMAL)
@@ -6995,7 +6999,7 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
69956999

69967000
/* Throttle based on the first usable node */
69977001
pgdat = zone->zone_pgdat;
6998-
if (allow_direct_reclaim(pgdat))
7002+
if (allow_direct_reclaim(pgdat, gfp_mask & __GFP_KSWAPD_RECLAIM))
69997003
goto out;
70007004
break;
70017005
}
@@ -7017,11 +7021,14 @@ static bool throttle_direct_reclaim(gfp_t gfp_mask, struct zonelist *zonelist,
70177021
*/
70187022
if (!(gfp_mask & __GFP_FS))
70197023
wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
7020-
allow_direct_reclaim(pgdat), HZ);
7024+
allow_direct_reclaim(pgdat, true), HZ);
70217025
else
70227026
/* Throttle until kswapd wakes the process */
70237027
wait_event_killable(zone->zone_pgdat->pfmemalloc_wait,
7024-
allow_direct_reclaim(pgdat));
7028+
allow_direct_reclaim(pgdat, true));
7029+
7030+
if (unlikely(!(gfp_mask & __GFP_KSWAPD_RECLAIM)))
7031+
atomic_long_dec(&kswapd_waiters);
70257032

70267033
if (fatal_signal_pending(current))
70277034
return true;
@@ -7519,14 +7526,15 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int highest_zoneidx)
75197526
* able to safely make forward progress. Wake them
75207527
*/
75217528
if (waitqueue_active(&pgdat->pfmemalloc_wait) &&
7522-
allow_direct_reclaim(pgdat))
7529+
allow_direct_reclaim(pgdat, true))
75237530
wake_up_all(&pgdat->pfmemalloc_wait);
75247531

75257532
/* Check if kswapd should be suspending */
75267533
__fs_reclaim_release(_THIS_IP_);
75277534
ret = try_to_freeze();
75287535
__fs_reclaim_acquire(_THIS_IP_);
7529-
if (ret || kthread_should_stop())
7536+
if (ret || kthread_should_stop() ||
7537+
!atomic_long_read(&kswapd_waiters))
75307538
break;
75317539

75327540
/*

0 commit comments

Comments
 (0)