Skip to content

Commit 344736f

Browse files
Vladimir Davydovhtejun
authored andcommitted
cpuset: simplify cpuset_node_allowed API
Current cpuset API for checking if a zone/node is allowed to allocate from looks rather awkward. We have hardwall and softwall versions of cpuset_node_allowed with the softwall version doing literally the same as the hardwall version if __GFP_HARDWALL is passed to it in gfp flags. If it isn't, the softwall version may check the given node against the enclosing hardwall cpuset, which it needs to take the callback lock to do. Such a distinction was introduced by commit 02a0e53 ("cpuset: rework cpuset_zone_allowed api"). Before, we had the only version with the __GFP_HARDWALL flag determining its behavior. The purpose of the commit was to avoid sleep-in-atomic bugs when someone would mistakenly call the function without the __GFP_HARDWALL flag for an atomic allocation. The suffixes introduced were intended to make the callers think before using the function. However, since the callback lock was converted from mutex to spinlock by the previous patch, the softwall check function cannot sleep, and these precautions are no longer necessary. So let's simplify the API back to the single check. Suggested-by: David Rientjes <[email protected]> Signed-off-by: Vladimir Davydov <[email protected]> Acked-by: Christoph Lameter <[email protected]> Acked-by: Zefan Li <[email protected]> Signed-off-by: Tejun Heo <[email protected]>
1 parent 8447a0f commit 344736f

8 files changed

Lines changed: 20 additions & 92 deletions

File tree

include/linux/cpuset.h

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,29 +48,16 @@ extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
4848
void cpuset_init_current_mems_allowed(void);
4949
int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask);
5050

51-
extern int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask);
52-
extern int __cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask);
51+
extern int __cpuset_node_allowed(int node, gfp_t gfp_mask);
5352

54-
static inline int cpuset_node_allowed_softwall(int node, gfp_t gfp_mask)
53+
static inline int cpuset_node_allowed(int node, gfp_t gfp_mask)
5554
{
56-
return nr_cpusets() <= 1 ||
57-
__cpuset_node_allowed_softwall(node, gfp_mask);
55+
return nr_cpusets() <= 1 || __cpuset_node_allowed(node, gfp_mask);
5856
}
5957

60-
static inline int cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask)
58+
static inline int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
6159
{
62-
return nr_cpusets() <= 1 ||
63-
__cpuset_node_allowed_hardwall(node, gfp_mask);
64-
}
65-
66-
static inline int cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
67-
{
68-
return cpuset_node_allowed_softwall(zone_to_nid(z), gfp_mask);
69-
}
70-
71-
static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
72-
{
73-
return cpuset_node_allowed_hardwall(zone_to_nid(z), gfp_mask);
60+
return cpuset_node_allowed(zone_to_nid(z), gfp_mask);
7461
}
7562

7663
extern int cpuset_mems_allowed_intersects(const struct task_struct *tsk1,
@@ -179,22 +166,12 @@ static inline int cpuset_nodemask_valid_mems_allowed(nodemask_t *nodemask)
179166
return 1;
180167
}
181168

182-
static inline int cpuset_node_allowed_softwall(int node, gfp_t gfp_mask)
183-
{
184-
return 1;
185-
}
186-
187-
static inline int cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask)
188-
{
189-
return 1;
190-
}
191-
192-
static inline int cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
169+
static inline int cpuset_node_allowed(int node, gfp_t gfp_mask)
193170
{
194171
return 1;
195172
}
196173

197-
static inline int cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask)
174+
static inline int cpuset_zone_allowed(struct zone *z, gfp_t gfp_mask)
198175
{
199176
return 1;
200177
}

kernel/cpuset.c

Lines changed: 2 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2453,7 +2453,7 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs)
24532453
}
24542454

24552455
/**
2456-
* cpuset_node_allowed_softwall - Can we allocate on a memory node?
2456+
* cpuset_node_allowed - Can we allocate on a memory node?
24572457
* @node: is this an allowed node?
24582458
* @gfp_mask: memory allocation flags
24592459
*
@@ -2465,13 +2465,6 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs)
24652465
* flag, yes.
24662466
* Otherwise, no.
24672467
*
2468-
* If __GFP_HARDWALL is set, cpuset_node_allowed_softwall() reduces to
2469-
* cpuset_node_allowed_hardwall(). Otherwise, cpuset_node_allowed_softwall()
2470-
* might sleep, and might allow a node from an enclosing cpuset.
2471-
*
2472-
* cpuset_node_allowed_hardwall() only handles the simpler case of hardwall
2473-
* cpusets, and never sleeps.
2474-
*
24752468
* The __GFP_THISNODE placement logic is really handled elsewhere,
24762469
* by forcibly using a zonelist starting at a specified node, and by
24772470
* (in get_page_from_freelist()) refusing to consider the zones for
@@ -2506,21 +2499,15 @@ static struct cpuset *nearest_hardwall_ancestor(struct cpuset *cs)
25062499
* TIF_MEMDIE - any node ok
25072500
* GFP_KERNEL - any node in enclosing hardwalled cpuset ok
25082501
* GFP_USER - only nodes in current tasks mems allowed ok.
2509-
*
2510-
* Rule:
2511-
* Don't call cpuset_node_allowed_softwall if you can't sleep, unless you
2512-
* pass in the __GFP_HARDWALL flag set in gfp_flag, which disables
2513-
* the code that might scan up ancestor cpusets and sleep.
25142502
*/
2515-
int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask)
2503+
int __cpuset_node_allowed(int node, gfp_t gfp_mask)
25162504
{
25172505
struct cpuset *cs; /* current cpuset ancestors */
25182506
int allowed; /* is allocation in zone z allowed? */
25192507
unsigned long flags;
25202508

25212509
if (in_interrupt() || (gfp_mask & __GFP_THISNODE))
25222510
return 1;
2523-
might_sleep_if(!(gfp_mask & __GFP_HARDWALL));
25242511
if (node_isset(node, current->mems_allowed))
25252512
return 1;
25262513
/*
@@ -2547,44 +2534,6 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask)
25472534
return allowed;
25482535
}
25492536

2550-
/*
2551-
* cpuset_node_allowed_hardwall - Can we allocate on a memory node?
2552-
* @node: is this an allowed node?
2553-
* @gfp_mask: memory allocation flags
2554-
*
2555-
* If we're in interrupt, yes, we can always allocate. If __GFP_THISNODE is
2556-
* set, yes, we can always allocate. If node is in our task's mems_allowed,
2557-
* yes. If the task has been OOM killed and has access to memory reserves as
2558-
* specified by the TIF_MEMDIE flag, yes.
2559-
* Otherwise, no.
2560-
*
2561-
* The __GFP_THISNODE placement logic is really handled elsewhere,
2562-
* by forcibly using a zonelist starting at a specified node, and by
2563-
* (in get_page_from_freelist()) refusing to consider the zones for
2564-
* any node on the zonelist except the first. By the time any such
2565-
* calls get to this routine, we should just shut up and say 'yes'.
2566-
*
2567-
* Unlike the cpuset_node_allowed_softwall() variant, above,
2568-
* this variant requires that the node be in the current task's
2569-
* mems_allowed or that we're in interrupt. It does not scan up the
2570-
* cpuset hierarchy for the nearest enclosing mem_exclusive cpuset.
2571-
* It never sleeps.
2572-
*/
2573-
int __cpuset_node_allowed_hardwall(int node, gfp_t gfp_mask)
2574-
{
2575-
if (in_interrupt() || (gfp_mask & __GFP_THISNODE))
2576-
return 1;
2577-
if (node_isset(node, current->mems_allowed))
2578-
return 1;
2579-
/*
2580-
* Allow tasks that have access to memory reserves because they have
2581-
* been OOM killed to get memory anywhere.
2582-
*/
2583-
if (unlikely(test_thread_flag(TIF_MEMDIE)))
2584-
return 1;
2585-
return 0;
2586-
}
2587-
25882537
/**
25892538
* cpuset_mem_spread_node() - On which node to begin search for a file page
25902539
* cpuset_slab_spread_node() - On which node to begin search for a slab page

mm/hugetlb.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h,
582582

583583
for_each_zone_zonelist_nodemask(zone, z, zonelist,
584584
MAX_NR_ZONES - 1, nodemask) {
585-
if (cpuset_zone_allowed_softwall(zone, htlb_alloc_mask(h))) {
585+
if (cpuset_zone_allowed(zone, htlb_alloc_mask(h))) {
586586
page = dequeue_huge_page_node(h, zone_to_nid(zone));
587587
if (page) {
588588
if (avoid_reserve)

mm/oom_kill.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ static enum oom_constraint constrained_alloc(struct zonelist *zonelist,
233233
/* Check this allocation failure is caused by cpuset's wall function */
234234
for_each_zone_zonelist_nodemask(zone, z, zonelist,
235235
high_zoneidx, nodemask)
236-
if (!cpuset_zone_allowed_softwall(zone, gfp_mask))
236+
if (!cpuset_zone_allowed(zone, gfp_mask))
237237
cpuset_limited = true;
238238

239239
if (cpuset_limited) {

mm/page_alloc.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,7 +1962,7 @@ get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order,
19621962

19631963
/*
19641964
* Scan zonelist, looking for a zone with enough free.
1965-
* See also __cpuset_node_allowed_softwall() comment in kernel/cpuset.c.
1965+
* See also __cpuset_node_allowed() comment in kernel/cpuset.c.
19661966
*/
19671967
for_each_zone_zonelist_nodemask(zone, z, zonelist,
19681968
high_zoneidx, nodemask) {
@@ -1973,7 +1973,7 @@ get_page_from_freelist(gfp_t gfp_mask, nodemask_t *nodemask, unsigned int order,
19731973
continue;
19741974
if (cpusets_enabled() &&
19751975
(alloc_flags & ALLOC_CPUSET) &&
1976-
!cpuset_zone_allowed_softwall(zone, gfp_mask))
1976+
!cpuset_zone_allowed(zone, gfp_mask))
19771977
continue;
19781978
/*
19791979
* Distribute pages in proportion to the individual
@@ -2514,7 +2514,7 @@ gfp_to_alloc_flags(gfp_t gfp_mask)
25142514
alloc_flags |= ALLOC_HARDER;
25152515
/*
25162516
* Ignore cpuset mems for GFP_ATOMIC rather than fail, see the
2517-
* comment for __cpuset_node_allowed_softwall().
2517+
* comment for __cpuset_node_allowed().
25182518
*/
25192519
alloc_flags &= ~ALLOC_CPUSET;
25202520
} else if (unlikely(rt_task(current)) && !in_interrupt())

mm/slab.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3012,7 +3012,7 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
30123012
for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) {
30133013
nid = zone_to_nid(zone);
30143014

3015-
if (cpuset_zone_allowed_hardwall(zone, flags) &&
3015+
if (cpuset_zone_allowed(zone, flags | __GFP_HARDWALL) &&
30163016
get_node(cache, nid) &&
30173017
get_node(cache, nid)->free_objects) {
30183018
obj = ____cache_alloc_node(cache,

mm/slub.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,8 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags,
16621662

16631663
n = get_node(s, zone_to_nid(zone));
16641664

1665-
if (n && cpuset_zone_allowed_hardwall(zone, flags) &&
1665+
if (n && cpuset_zone_allowed(zone,
1666+
flags | __GFP_HARDWALL) &&
16661667
n->nr_partial > s->min_partial) {
16671668
object = get_partial_node(s, n, c, flags);
16681669
if (object) {

mm/vmscan.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,7 +2405,8 @@ static bool shrink_zones(struct zonelist *zonelist, struct scan_control *sc)
24052405
* to global LRU.
24062406
*/
24072407
if (global_reclaim(sc)) {
2408-
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
2408+
if (!cpuset_zone_allowed(zone,
2409+
GFP_KERNEL | __GFP_HARDWALL))
24092410
continue;
24102411

24112412
lru_pages += zone_reclaimable_pages(zone);
@@ -3388,7 +3389,7 @@ void wakeup_kswapd(struct zone *zone, int order, enum zone_type classzone_idx)
33883389
if (!populated_zone(zone))
33893390
return;
33903391

3391-
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
3392+
if (!cpuset_zone_allowed(zone, GFP_KERNEL | __GFP_HARDWALL))
33923393
return;
33933394
pgdat = zone->zone_pgdat;
33943395
if (pgdat->kswapd_max_order < order) {

0 commit comments

Comments
 (0)