1 | v1 -> v2: | ||
---|---|---|---|
2 | - Remove status_change_nid_normal and the code that | ||
3 | deals with it (David & Vlastimil) | ||
4 | - Remove slab_mem_offline_callback (David & Vlastimil) | ||
5 | - Change the order of canceling the notifiers | ||
6 | in {online,offline}_pages (Vlastimil) | ||
7 | - Fix up a couple of whitespaces (Jonathan Cameron) | ||
8 | - Add RBs-by | ||
9 | |||
1 | Memory notifier is a tool that allow consumers to get notified whenever | 10 | Memory notifier is a tool that allow consumers to get notified whenever |
2 | memory gets onlined or offlined in the system. | 11 | memory gets onlined or offlined in the system. |
3 | Currently, there are 10 consumers of that, but 5 out of those 10 consumers | 12 | Currently, there are 10 consumers of that, but 5 out of those 10 consumers |
4 | are only interested in getting notifications when a numa node has changed its | 13 | are only interested in getting notifications when a numa node changes its |
5 | state. | 14 | memory state. |
6 | That means going from memoryless to memory-aware of vice versa. | 15 | That means going from memoryless to memory-aware of vice versa. |
7 | 16 | ||
8 | Which means that for every {online,offline}_pages operation they get | 17 | Which means that for every {online,offline}_pages operation they get |
9 | notified even though the numa node might not have changed its state. | 18 | notified even though the numa node might not have changed its state. |
10 | 19 | ||
11 | The first patch implements a numa node notifier that does just that, and have | 20 | While we are doing this, remove status_change_nid_normal, as the only |
21 | current user (slub) does not really need it. | ||
22 | This allows us to further simplify and clean up the code. | ||
23 | |||
24 | The first patch gets rid of status_change_nid_normal in slub. | ||
25 | The second patch implements a numa node notifier that does just that, and have | ||
12 | those consumers register in there, so they get notified only when they are | 26 | those consumers register in there, so they get notified only when they are |
13 | interested. | 27 | interested. |
14 | 28 | ||
15 | The second patch replaces 'status_change_normal{_normal}' fields within | 29 | The third patch replaces 'status_change_nid{_normal}' fields within |
16 | memory_notify with a 'nid', as that is only what we need for memory | 30 | memory_notify with a 'nid', as that is only what we need for memory |
17 | notifer and update the only user of it (page_ext). | 31 | notifer and update the only user of it (page_ext). |
18 | 32 | ||
19 | Consumers that are only interested in numa node states change are: | 33 | Consumers that are only interested in numa node states change are: |
20 | 34 | ||
21 | - memory-tier | 35 | - memory-tier |
22 | - slub | 36 | - slub |
23 | - cpuset | 37 | - cpuset |
24 | - hmat | 38 | - hmat |
25 | - cxl | 39 | - cxl |
26 | 40 | ||
41 | Oscar Salvador (3): | ||
42 | mm,slub: Do not special case N_NORMAL nodes for slab_nodes | ||
43 | mm,memory_hotplug: Implement numa node notifier | ||
44 | mm,memory_hotplug: Rename status_change_nid parameter in memory_notify | ||
27 | 45 | ||
28 | Oscar Salvador (2): | 46 | drivers/acpi/numa/hmat.c | 6 +- |
29 | mm,memory_hotplug: Implement numa node notifier | 47 | drivers/base/node.c | 19 +++++++ |
30 | mm,memory_hotplug: Replace status_change_nid parameter in | 48 | drivers/cxl/core/region.c | 14 ++--- |
31 | memory_notify | 49 | drivers/cxl/cxl.h | 4 +- |
32 | 50 | include/linux/memory.h | 38 ++++++++++++- | |
33 | drivers/acpi/numa/hmat.c | 6 +-- | 51 | kernel/cgroup/cpuset.c | 2 +- |
34 | drivers/base/node.c | 19 +++++++++ | 52 | mm/memory-tiers.c | 8 +-- |
35 | drivers/cxl/core/region.c | 14 +++---- | 53 | mm/memory_hotplug.c | 117 +++++++++++++++++++++----------------- |
36 | drivers/cxl/cxl.h | 4 +- | 54 | mm/page_ext.c | 12 +--- |
37 | include/linux/memory.h | 37 ++++++++++++++++++ | 55 | mm/slub.c | 41 ++----------- |
38 | kernel/cgroup/cpuset.c | 2 +- | 56 | 10 files changed, 145 insertions(+), 116 deletions(-) |
39 | mm/memory-tiers.c | 8 ++-- | ||
40 | mm/memory_hotplug.c | 82 +++++++++++++++++++++++++++++---------- | ||
41 | mm/page_ext.c | 12 +----- | ||
42 | mm/slub.c | 22 +++++------ | ||
43 | 10 files changed, 146 insertions(+), 60 deletions(-) | ||
44 | 57 | ||
45 | -- | 58 | -- |
46 | 2.49.0 | 59 | 2.49.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | Currently, slab_mem_going_going_callback() checks whether the node has | ||
2 | N_NORMAL memory in order to be set in slab_nodes. | ||
3 | While it is true that gettind rid of that enforcing would mean | ||
4 | ending up with movables nodes in slab_nodes, the memory waste that comes | ||
5 | with that is negligible. | ||
1 | 6 | ||
7 | So stop checking for status_change_nid_normal and just use status_change_nid | ||
8 | instead which works for both types of memory. | ||
9 | |||
10 | Also, once we allocate the kmem_cache_node cache for the node in | ||
11 | slab_mem_online_callback(), we never deallocate it in | ||
12 | slab_mem_off_callback() when the node goes memoryless, so we can just | ||
13 | get rid of it. | ||
14 | |||
15 | The only side effect is that we will stop clearing the node from slab_nodes. | ||
16 | |||
17 | Signed-off-by: Oscar Salvador <osalvador@suse.de> | ||
18 | --- | ||
19 | mm/slub.c | 30 +----------------------------- | ||
20 | 1 file changed, 1 insertion(+), 29 deletions(-) | ||
21 | |||
22 | diff --git a/mm/slub.c b/mm/slub.c | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/mm/slub.c | ||
25 | +++ b/mm/slub.c | ||
26 | @@ -XXX,XX +XXX,XX @@ static int slab_mem_going_offline_callback(void *arg) | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | -static void slab_mem_offline_callback(void *arg) | ||
31 | -{ | ||
32 | - struct memory_notify *marg = arg; | ||
33 | - int offline_node; | ||
34 | - | ||
35 | - offline_node = marg->status_change_nid_normal; | ||
36 | - | ||
37 | - /* | ||
38 | - * If the node still has available memory. we need kmem_cache_node | ||
39 | - * for it yet. | ||
40 | - */ | ||
41 | - if (offline_node < 0) | ||
42 | - return; | ||
43 | - | ||
44 | - mutex_lock(&slab_mutex); | ||
45 | - node_clear(offline_node, slab_nodes); | ||
46 | - /* | ||
47 | - * We no longer free kmem_cache_node structures here, as it would be | ||
48 | - * racy with all get_node() users, and infeasible to protect them with | ||
49 | - * slab_mutex. | ||
50 | - */ | ||
51 | - mutex_unlock(&slab_mutex); | ||
52 | -} | ||
53 | - | ||
54 | static int slab_mem_going_online_callback(void *arg) | ||
55 | { | ||
56 | struct kmem_cache_node *n; | ||
57 | struct kmem_cache *s; | ||
58 | struct memory_notify *marg = arg; | ||
59 | - int nid = marg->status_change_nid_normal; | ||
60 | + int nid = marg->status_change_nid; | ||
61 | int ret = 0; | ||
62 | |||
63 | /* | ||
64 | @@ -XXX,XX +XXX,XX @@ static int slab_memory_callback(struct notifier_block *self, | ||
65 | case MEM_GOING_OFFLINE: | ||
66 | ret = slab_mem_going_offline_callback(arg); | ||
67 | break; | ||
68 | - case MEM_OFFLINE: | ||
69 | - case MEM_CANCEL_ONLINE: | ||
70 | - slab_mem_offline_callback(arg); | ||
71 | - break; | ||
72 | case MEM_ONLINE: | ||
73 | case MEM_CANCEL_OFFLINE: | ||
74 | break; | ||
75 | -- | ||
76 | 2.49.0 | diff view generated by jsdifflib |
1 | There are at least four consumers of hotplug_memory_notifier that what they | 1 | There are at least five consumers of hotplug_memory_notifier that what they |
---|---|---|---|
2 | really are interested in is whether any numa node changed its state, e.g: going | 2 | really are interested in is whether any numa node changed its state, e.g: going |
3 | from being memory aware to becoming memoryless. | 3 | from being memory aware to becoming memoryless and vice versa. |
4 | 4 | ||
5 | Implement a specific notifier for numa nodes when their state gets changed, | 5 | Implement a specific notifier for numa nodes when their state gets changed, |
6 | and have those consumers that only care about numa node state changes use it. | 6 | and have those consumers that only care about numa node state changes use it. |
7 | 7 | ||
8 | Signed-off-by: Oscar Salvador <osalvador@suse.de> | 8 | Signed-off-by: Oscar Salvador <osalvador@suse.de> |
9 | Reviewed-by: Harry Yoo <harry.yoo@oracle.com> | ||
10 | Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> | ||
9 | --- | 11 | --- |
10 | drivers/acpi/numa/hmat.c | 6 +-- | 12 | drivers/acpi/numa/hmat.c | 6 +- |
11 | drivers/base/node.c | 19 +++++++++ | 13 | drivers/base/node.c | 19 +++++++ |
12 | drivers/cxl/core/region.c | 14 +++---- | 14 | drivers/cxl/core/region.c | 14 ++--- |
13 | drivers/cxl/cxl.h | 4 +- | 15 | drivers/cxl/cxl.h | 4 +- |
14 | include/linux/memory.h | 38 ++++++++++++++++++ | 16 | include/linux/memory.h | 38 ++++++++++++- |
15 | kernel/cgroup/cpuset.c | 2 +- | 17 | kernel/cgroup/cpuset.c | 2 +- |
16 | mm/memory-tiers.c | 8 ++-- | 18 | mm/memory-tiers.c | 8 +-- |
17 | mm/memory_hotplug.c | 84 +++++++++++++++++++++++++++++---------- | 19 | mm/memory_hotplug.c | 117 +++++++++++++++++++++----------------- |
18 | mm/slub.c | 22 +++++----- | 20 | mm/slub.c | 13 ++--- |
19 | 9 files changed, 148 insertions(+), 49 deletions(-) | 21 | 9 files changed, 144 insertions(+), 77 deletions(-) |
20 | 22 | ||
21 | diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c | 23 | diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c |
22 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/drivers/acpi/numa/hmat.c | 25 | --- a/drivers/acpi/numa/hmat.c |
24 | +++ b/drivers/acpi/numa/hmat.c | 26 | +++ b/drivers/acpi/numa/hmat.c |
... | ... | ||
156 | + | 158 | + |
157 | struct memory_notify { | 159 | struct memory_notify { |
158 | /* | 160 | /* |
159 | * The altmap_start_pfn and altmap_nr_pages fields are designated for | 161 | * The altmap_start_pfn and altmap_nr_pages fields are designated for |
160 | @@ -XXX,XX +XXX,XX @@ struct memory_notify { | 162 | @@ -XXX,XX +XXX,XX @@ struct memory_notify { |
163 | unsigned long altmap_nr_pages; | ||
164 | unsigned long start_pfn; | ||
165 | unsigned long nr_pages; | ||
166 | - int status_change_nid_normal; | ||
167 | + int status_change_nid; | ||
168 | +}; | ||
169 | + | ||
170 | +struct node_notify { | ||
161 | int status_change_nid; | 171 | int status_change_nid; |
162 | }; | 172 | }; |
163 | |||
164 | +struct node_notify { | ||
165 | + int status_change_nid_normal; | ||
166 | + int status_change_nid; | ||
167 | +}; | ||
168 | + | ||
169 | struct notifier_block; | ||
170 | struct mem_section; | ||
171 | 173 | ||
172 | @@ -XXX,XX +XXX,XX @@ static inline int hotplug_memory_notifier(notifier_fn_t fn, int pri) | 174 | @@ -XXX,XX +XXX,XX @@ static inline int hotplug_memory_notifier(notifier_fn_t fn, int pri) |
173 | { | 175 | { |
174 | return 0; | 176 | return 0; |
175 | } | 177 | } |
... | ... | ||
279 | - struct zone *zone, struct memory_notify *arg) | 281 | - struct zone *zone, struct memory_notify *arg) |
280 | + struct zone *zone, struct node_notify *arg) | 282 | + struct zone *zone, struct node_notify *arg) |
281 | { | 283 | { |
282 | int nid = zone_to_nid(zone); | 284 | int nid = zone_to_nid(zone); |
283 | 285 | ||
284 | @@ -XXX,XX +XXX,XX @@ static void node_states_check_changes_online(unsigned long nr_pages, | 286 | arg->status_change_nid = NUMA_NO_NODE; |
285 | arg->status_change_nid_normal = nid; | 287 | - arg->status_change_nid_normal = NUMA_NO_NODE; |
286 | } | 288 | |
289 | if (!node_state(nid, N_MEMORY)) | ||
290 | arg->status_change_nid = nid; | ||
291 | - if (zone_idx(zone) <= ZONE_NORMAL && !node_state(nid, N_NORMAL_MEMORY)) | ||
292 | - arg->status_change_nid_normal = nid; | ||
293 | } | ||
287 | 294 | ||
288 | -static void node_states_set_node(int node, struct memory_notify *arg) | 295 | -static void node_states_set_node(int node, struct memory_notify *arg) |
289 | +static void node_states_set_node(int node, struct node_notify *arg) | 296 | +static void node_states_set_node(int node, struct node_notify *arg) |
290 | { | 297 | { |
291 | if (arg->status_change_nid_normal >= 0) | 298 | - if (arg->status_change_nid_normal >= 0) |
292 | node_set_state(node, N_NORMAL_MEMORY); | 299 | - node_set_state(node, N_NORMAL_MEMORY); |
300 | - | ||
301 | if (arg->status_change_nid >= 0) | ||
302 | node_set_state(node, N_MEMORY); | ||
303 | } | ||
293 | @@ -XXX,XX +XXX,XX @@ int online_pages(unsigned long pfn, unsigned long nr_pages, | 304 | @@ -XXX,XX +XXX,XX @@ int online_pages(unsigned long pfn, unsigned long nr_pages, |
294 | int need_zonelists_rebuild = 0; | 305 | int need_zonelists_rebuild = 0; |
295 | const int nid = zone_to_nid(zone); | 306 | const int nid = zone_to_nid(zone); |
296 | int ret; | 307 | int ret; |
297 | - struct memory_notify arg; | 308 | - struct memory_notify arg; |
... | ... | ||
309 | - arg.nr_pages = nr_pages; | 320 | - arg.nr_pages = nr_pages; |
310 | - node_states_check_changes_online(nr_pages, zone, &arg); | 321 | - node_states_check_changes_online(nr_pages, zone, &arg); |
311 | + mem_arg.start_pfn = pfn; | 322 | + mem_arg.start_pfn = pfn; |
312 | + mem_arg.nr_pages = nr_pages; | 323 | + mem_arg.nr_pages = nr_pages; |
313 | + node_states_check_changes_online(nr_pages, zone, &node_arg); | 324 | + node_states_check_changes_online(nr_pages, zone, &node_arg); |
314 | 325 | + | |
315 | - ret = memory_notify(MEM_GOING_ONLINE, &arg); | ||
316 | + if (node_arg.status_change_nid >= 0) { | 326 | + if (node_arg.status_change_nid >= 0) { |
317 | + /* Node is becoming memory aware. Notify consumers */ | 327 | + /* Node is becoming memory aware. Notify consumers */ |
318 | + cancel_node_notifier_on_err = true; | 328 | + cancel_node_notifier_on_err = true; |
319 | + ret = node_notify(NODE_BECOMING_MEM_AWARE, &node_arg); | 329 | + ret = node_notify(NODE_BECOMING_MEM_AWARE, &node_arg); |
320 | + ret = notifier_to_errno(ret); | 330 | + ret = notifier_to_errno(ret); |
321 | + if (ret) | 331 | + if (ret) |
322 | + goto failed_addition; | 332 | + goto failed_addition; |
323 | + } | 333 | + } |
324 | + | 334 | |
335 | - ret = memory_notify(MEM_GOING_ONLINE, &arg); | ||
325 | + cancel_mem_notifier_on_err = true; | 336 | + cancel_mem_notifier_on_err = true; |
326 | + mem_arg.status_change_nid = node_arg.status_change_nid; | 337 | + mem_arg.status_change_nid = node_arg.status_change_nid; |
327 | + mem_arg.status_change_nid_normal = node_arg.status_change_nid_normal; | ||
328 | + ret = memory_notify(MEM_GOING_ONLINE, &mem_arg); | 338 | + ret = memory_notify(MEM_GOING_ONLINE, &mem_arg); |
329 | ret = notifier_to_errno(ret); | 339 | ret = notifier_to_errno(ret); |
330 | if (ret) | 340 | if (ret) |
331 | goto failed_addition; | 341 | goto failed_addition; |
332 | @@ -XXX,XX +XXX,XX @@ int online_pages(unsigned long pfn, unsigned long nr_pages, | 342 | @@ -XXX,XX +XXX,XX @@ int online_pages(unsigned long pfn, unsigned long nr_pages, |
... | ... | ||
358 | failed_addition: | 368 | failed_addition: |
359 | pr_debug("online_pages [mem %#010llx-%#010llx] failed\n", | 369 | pr_debug("online_pages [mem %#010llx-%#010llx] failed\n", |
360 | (unsigned long long) pfn << PAGE_SHIFT, | 370 | (unsigned long long) pfn << PAGE_SHIFT, |
361 | (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1); | 371 | (((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1); |
362 | - memory_notify(MEM_CANCEL_ONLINE, &arg); | 372 | - memory_notify(MEM_CANCEL_ONLINE, &arg); |
373 | + if (cancel_mem_notifier_on_err) | ||
374 | + memory_notify(MEM_CANCEL_ONLINE, &mem_arg); | ||
363 | + if (cancel_node_notifier_on_err) | 375 | + if (cancel_node_notifier_on_err) |
364 | + node_notify(NODE_CANCEL_MEM_AWARE, &node_arg); | 376 | + node_notify(NODE_CANCEL_MEM_AWARE, &node_arg); |
365 | + if (cancel_mem_notifier_on_err) | ||
366 | + memory_notify(MEM_CANCEL_ONLINE, &mem_arg); | ||
367 | remove_pfn_range_from_zone(zone, pfn, nr_pages); | 377 | remove_pfn_range_from_zone(zone, pfn, nr_pages); |
368 | return ret; | 378 | return ret; |
369 | } | 379 | } |
370 | @@ -XXX,XX +XXX,XX @@ early_param("movable_node", cmdline_parse_movable_node); | 380 | @@ -XXX,XX +XXX,XX @@ early_param("movable_node", cmdline_parse_movable_node); |
371 | 381 | ||
... | ... | ||
374 | - struct zone *zone, struct memory_notify *arg) | 384 | - struct zone *zone, struct memory_notify *arg) |
375 | + struct zone *zone, struct node_notify *arg) | 385 | + struct zone *zone, struct node_notify *arg) |
376 | { | 386 | { |
377 | struct pglist_data *pgdat = zone->zone_pgdat; | 387 | struct pglist_data *pgdat = zone->zone_pgdat; |
378 | unsigned long present_pages = 0; | 388 | unsigned long present_pages = 0; |
379 | @@ -XXX,XX +XXX,XX @@ static void node_states_check_changes_offline(unsigned long nr_pages, | 389 | enum zone_type zt; |
390 | |||
391 | arg->status_change_nid = NUMA_NO_NODE; | ||
392 | - arg->status_change_nid_normal = NUMA_NO_NODE; | ||
393 | |||
394 | /* | ||
395 | - * Check whether node_states[N_NORMAL_MEMORY] will be changed. | ||
396 | - * If the memory to be offline is within the range | ||
397 | - * [0..ZONE_NORMAL], and it is the last present memory there, | ||
398 | - * the zones in that range will become empty after the offlining, | ||
399 | - * thus we can determine that we need to clear the node from | ||
400 | - * node_states[N_NORMAL_MEMORY]. | ||
401 | + * Here we count the possible pages within the range [0..ZONE_MOVABLE]. | ||
402 | + * If after having accounted all the pages, we see that the nr_pages to | ||
403 | + * be offlined is over or equal to the accounted pages, we know that the | ||
404 | + * node will become empty, ans so, we can clear it for N_MEMORY. | ||
405 | */ | ||
406 | - for (zt = 0; zt <= ZONE_NORMAL; zt++) | ||
407 | + for (zt = 0; zt <= ZONE_MOVABLE; zt++) | ||
408 | present_pages += pgdat->node_zones[zt].present_pages; | ||
409 | - if (zone_idx(zone) <= ZONE_NORMAL && nr_pages >= present_pages) | ||
410 | - arg->status_change_nid_normal = zone_to_nid(zone); | ||
411 | - | ||
412 | - /* | ||
413 | - * We have accounted the pages from [0..ZONE_NORMAL); ZONE_HIGHMEM | ||
414 | - * does not apply as we don't support 32bit. | ||
415 | - * Here we count the possible pages from ZONE_MOVABLE. | ||
416 | - * If after having accounted all the pages, we see that the nr_pages | ||
417 | - * to be offlined is over or equal to the accounted pages, | ||
418 | - * we know that the node will become empty, and so, we can clear | ||
419 | - * it for N_MEMORY as well. | ||
420 | - */ | ||
421 | - present_pages += pgdat->node_zones[ZONE_MOVABLE].present_pages; | ||
422 | |||
423 | if (nr_pages >= present_pages) | ||
380 | arg->status_change_nid = zone_to_nid(zone); | 424 | arg->status_change_nid = zone_to_nid(zone); |
381 | } | 425 | } |
382 | 426 | ||
383 | -static void node_states_clear_node(int node, struct memory_notify *arg) | 427 | -static void node_states_clear_node(int node, struct memory_notify *arg) |
384 | +static void node_states_clear_node(int node, struct node_notify *arg) | 428 | +static void node_states_clear_node(int node, struct node_notify *arg) |
385 | { | 429 | { |
386 | if (arg->status_change_nid_normal >= 0) | 430 | - if (arg->status_change_nid_normal >= 0) |
387 | node_clear_state(node, N_NORMAL_MEMORY); | 431 | - node_clear_state(node, N_NORMAL_MEMORY); |
432 | - | ||
433 | if (arg->status_change_nid >= 0) | ||
434 | node_clear_state(node, N_MEMORY); | ||
435 | } | ||
388 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, | 436 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, |
389 | unsigned long pfn, managed_pages, system_ram_pages = 0; | 437 | unsigned long pfn, managed_pages, system_ram_pages = 0; |
390 | const int node = zone_to_nid(zone); | 438 | const int node = zone_to_nid(zone); |
391 | unsigned long flags; | 439 | unsigned long flags; |
392 | - struct memory_notify arg; | 440 | - struct memory_notify arg; |
... | ... | ||
416 | + } | 464 | + } |
417 | 465 | ||
418 | - ret = memory_notify(MEM_GOING_OFFLINE, &arg); | 466 | - ret = memory_notify(MEM_GOING_OFFLINE, &arg); |
419 | + cancel_mem_notifier_on_err = true; | 467 | + cancel_mem_notifier_on_err = true; |
420 | + mem_arg.status_change_nid = node_arg.status_change_nid; | 468 | + mem_arg.status_change_nid = node_arg.status_change_nid; |
421 | + mem_arg.status_change_nid_normal = node_arg.status_change_nid_normal; | ||
422 | + ret = memory_notify(MEM_GOING_OFFLINE, &mem_arg); | 469 | + ret = memory_notify(MEM_GOING_OFFLINE, &mem_arg); |
423 | ret = notifier_to_errno(ret); | 470 | ret = notifier_to_errno(ret); |
424 | if (ret) { | 471 | if (ret) { |
425 | reason = "notifier failure"; | 472 | reason = "notifier failure"; |
426 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, | 473 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, |
... | ... | ||
436 | 483 | ||
437 | - if (arg.status_change_nid >= 0) { | 484 | - if (arg.status_change_nid >= 0) { |
438 | + if (node_arg.status_change_nid >= 0) { | 485 | + if (node_arg.status_change_nid >= 0) { |
439 | kcompactd_stop(node); | 486 | kcompactd_stop(node); |
440 | kswapd_stop(node); | 487 | kswapd_stop(node); |
441 | + /*Node went memoryless. Notifiy interested consumers */ | 488 | + /* Node went memoryless. Notifiy interested consumers */ |
442 | + node_notify(NODE_BECAME_MEMORYLESS, &node_arg); | 489 | + node_notify(NODE_BECAME_MEMORYLESS, &node_arg); |
443 | } | 490 | } |
444 | 491 | ||
445 | writeback_set_ratelimit(); | 492 | writeback_set_ratelimit(); |
446 | 493 | ||
... | ... | ||
451 | 498 | ||
452 | failed_removal_isolated: | 499 | failed_removal_isolated: |
453 | /* pushback to free area */ | 500 | /* pushback to free area */ |
454 | undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE); | 501 | undo_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE); |
455 | - memory_notify(MEM_CANCEL_OFFLINE, &arg); | 502 | - memory_notify(MEM_CANCEL_OFFLINE, &arg); |
503 | + if (cancel_mem_notifier_on_err) | ||
504 | + memory_notify(MEM_CANCEL_OFFLINE, &mem_arg); | ||
456 | + if (cancel_node_notifier_on_err) | 505 | + if (cancel_node_notifier_on_err) |
457 | + node_notify(NODE_CANCEL_MEMORYLESS, &node_arg); | 506 | + node_notify(NODE_CANCEL_MEMORYLESS, &node_arg); |
458 | + if (cancel_mem_notifier_on_err) | ||
459 | + memory_notify(MEM_CANCEL_OFFLINE, &mem_arg); | ||
460 | failed_removal_pcplists_disabled: | 507 | failed_removal_pcplists_disabled: |
461 | lru_cache_enable(); | 508 | lru_cache_enable(); |
462 | zone_pcp_enable(zone); | 509 | zone_pcp_enable(zone); |
463 | diff --git a/mm/slub.c b/mm/slub.c | 510 | diff --git a/mm/slub.c b/mm/slub.c |
464 | index XXXXXXX..XXXXXXX 100644 | 511 | index XXXXXXX..XXXXXXX 100644 |
465 | --- a/mm/slub.c | 512 | --- a/mm/slub.c |
466 | +++ b/mm/slub.c | 513 | +++ b/mm/slub.c |
467 | @@ -XXX,XX +XXX,XX @@ static int slab_mem_going_offline_callback(void *arg) | ||
468 | |||
469 | static void slab_mem_offline_callback(void *arg) | ||
470 | { | ||
471 | - struct memory_notify *marg = arg; | ||
472 | + struct node_notify *narg = arg; | ||
473 | int offline_node; | ||
474 | |||
475 | - offline_node = marg->status_change_nid_normal; | ||
476 | + offline_node = narg->status_change_nid_normal; | ||
477 | |||
478 | /* | ||
479 | * If the node still has available memory. we need kmem_cache_node | ||
480 | @@ -XXX,XX +XXX,XX @@ static int slab_mem_going_online_callback(void *arg) | 514 | @@ -XXX,XX +XXX,XX @@ static int slab_mem_going_online_callback(void *arg) |
481 | { | 515 | { |
482 | struct kmem_cache_node *n; | 516 | struct kmem_cache_node *n; |
483 | struct kmem_cache *s; | 517 | struct kmem_cache *s; |
484 | - struct memory_notify *marg = arg; | 518 | - struct memory_notify *marg = arg; |
485 | - int nid = marg->status_change_nid_normal; | 519 | - int nid = marg->status_change_nid; |
486 | + struct node_notify *narg = arg; | 520 | + struct node_notify *narg = arg; |
487 | + int nid = narg->status_change_nid_normal; | 521 | + int nid = narg->status_change_nid; |
488 | int ret = 0; | 522 | int ret = 0; |
489 | 523 | ||
490 | /* | 524 | /* |
491 | @@ -XXX,XX +XXX,XX @@ static int slab_memory_callback(struct notifier_block *self, | 525 | @@ -XXX,XX +XXX,XX @@ static int slab_memory_callback(struct notifier_block *self, |
492 | int ret = 0; | 526 | int ret = 0; |
... | ... | ||
498 | break; | 532 | break; |
499 | - case MEM_GOING_OFFLINE: | 533 | - case MEM_GOING_OFFLINE: |
500 | + case NODE_BECOMING_MEMORYLESS: | 534 | + case NODE_BECOMING_MEMORYLESS: |
501 | ret = slab_mem_going_offline_callback(arg); | 535 | ret = slab_mem_going_offline_callback(arg); |
502 | break; | 536 | break; |
503 | - case MEM_OFFLINE: | ||
504 | - case MEM_CANCEL_ONLINE: | ||
505 | + case NODE_BECAME_MEMORYLESS: | ||
506 | + case NODE_CANCEL_MEM_AWARE: | ||
507 | slab_mem_offline_callback(arg); | ||
508 | break; | ||
509 | - case MEM_ONLINE: | 537 | - case MEM_ONLINE: |
510 | - case MEM_CANCEL_OFFLINE: | 538 | - case MEM_CANCEL_OFFLINE: |
511 | + case NODE_BECAME_MEM_AWARE: | 539 | - break; |
512 | + case NODE_CANCEL_MEMORYLESS: | ||
513 | break; | ||
514 | } | 540 | } |
515 | if (ret) | 541 | if (ret) |
542 | ret = notifier_from_errno(ret); | ||
516 | @@ -XXX,XX +XXX,XX @@ void __init kmem_cache_init(void) | 543 | @@ -XXX,XX +XXX,XX @@ void __init kmem_cache_init(void) |
517 | sizeof(struct kmem_cache_node), | 544 | sizeof(struct kmem_cache_node), |
518 | SLAB_HWCACHE_ALIGN | SLAB_NO_OBJ_EXT, 0, 0); | 545 | SLAB_HWCACHE_ALIGN | SLAB_NO_OBJ_EXT, 0, 0); |
519 | 546 | ||
520 | - hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI); | 547 | - hotplug_memory_notifier(slab_memory_callback, SLAB_CALLBACK_PRI); |
521 | + hotplug_node_notifier(slab_memory_callback, SLAB_CALLBACK_PRI); | 548 | + hotplug_node_notifier(slab_memory_callback, SLAB_CALLBACK_PRI); |
522 | 549 | ||
523 | /* Able to allocate the per node structures */ | 550 | /* Able to allocate the per node structures */ |
524 | slab_state = PARTIAL; | 551 | slab_state = PARTIAL; |
525 | -- | 552 | -- |
526 | 2.49.0 | 553 | 2.49.0 | diff view generated by jsdifflib |
1 | memory notify consumers are only interested in which node the memory we | 1 | The 'status_change_nid' field was used to track changes in the memory |
---|---|---|---|
2 | are adding belongs to, so replace current status_change_nid{_normal} fields | 2 | state of a numa node, but that funcionality has been decoupled from |
3 | with only one that specifies the node. | 3 | memory_notify and moved to node_notify. |
4 | Current consumers of memory_notify are only interested in which node the | ||
5 | memory we are adding belongs to, so rename current 'status_change_nid' | ||
6 | to 'nid'. | ||
4 | 7 | ||
5 | Signed-off-by: Oscar Salvador <osalvador@suse.de> | 8 | Signed-off-by: Oscar Salvador <osalvador@suse.de> |
9 | Reviewed-by: Harry Yoo <harry.yoo@oracle.com> | ||
10 | Reviewed-by: Vlastimil Babka <vbabka@suse.cz> | ||
6 | --- | 11 | --- |
7 | include/linux/memory.h | 3 +-- | 12 | include/linux/memory.h | 2 +- |
8 | mm/memory_hotplug.c | 6 ++---- | 13 | mm/memory_hotplug.c | 4 ++-- |
9 | mm/page_ext.c | 12 +----------- | 14 | mm/page_ext.c | 12 +----------- |
10 | 3 files changed, 4 insertions(+), 17 deletions(-) | 15 | 3 files changed, 4 insertions(+), 14 deletions(-) |
11 | 16 | ||
12 | diff --git a/include/linux/memory.h b/include/linux/memory.h | 17 | diff --git a/include/linux/memory.h b/include/linux/memory.h |
13 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/include/linux/memory.h | 19 | --- a/include/linux/memory.h |
15 | +++ b/include/linux/memory.h | 20 | +++ b/include/linux/memory.h |
16 | @@ -XXX,XX +XXX,XX @@ struct memory_notify { | 21 | @@ -XXX,XX +XXX,XX @@ struct memory_notify { |
17 | unsigned long altmap_nr_pages; | 22 | unsigned long altmap_nr_pages; |
18 | unsigned long start_pfn; | 23 | unsigned long start_pfn; |
19 | unsigned long nr_pages; | 24 | unsigned long nr_pages; |
20 | - int status_change_nid_normal; | ||
21 | - int status_change_nid; | 25 | - int status_change_nid; |
22 | + int nid; | 26 | + int nid; |
23 | }; | 27 | }; |
24 | 28 | ||
25 | struct node_notify { | 29 | struct node_notify { |
... | ... | ||
38 | @@ -XXX,XX +XXX,XX @@ int online_pages(unsigned long pfn, unsigned long nr_pages, | 42 | @@ -XXX,XX +XXX,XX @@ int online_pages(unsigned long pfn, unsigned long nr_pages, |
39 | } | 43 | } |
40 | 44 | ||
41 | cancel_mem_notifier_on_err = true; | 45 | cancel_mem_notifier_on_err = true; |
42 | - mem_arg.status_change_nid = node_arg.status_change_nid; | 46 | - mem_arg.status_change_nid = node_arg.status_change_nid; |
43 | - mem_arg.status_change_nid_normal = node_arg.status_change_nid_normal; | ||
44 | ret = memory_notify(MEM_GOING_ONLINE, &mem_arg); | 47 | ret = memory_notify(MEM_GOING_ONLINE, &mem_arg); |
45 | ret = notifier_to_errno(ret); | 48 | ret = notifier_to_errno(ret); |
46 | if (ret) | 49 | if (ret) |
47 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, | 50 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, |
48 | 51 | ||
... | ... | ||
55 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, | 58 | @@ -XXX,XX +XXX,XX @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages, |
56 | } | 59 | } |
57 | 60 | ||
58 | cancel_mem_notifier_on_err = true; | 61 | cancel_mem_notifier_on_err = true; |
59 | - mem_arg.status_change_nid = node_arg.status_change_nid; | 62 | - mem_arg.status_change_nid = node_arg.status_change_nid; |
60 | - mem_arg.status_change_nid_normal = node_arg.status_change_nid_normal; | ||
61 | ret = memory_notify(MEM_GOING_OFFLINE, &mem_arg); | 63 | ret = memory_notify(MEM_GOING_OFFLINE, &mem_arg); |
62 | ret = notifier_to_errno(ret); | 64 | ret = notifier_to_errno(ret); |
63 | if (ret) { | 65 | if (ret) { |
64 | diff --git a/mm/page_ext.c b/mm/page_ext.c | 66 | diff --git a/mm/page_ext.c b/mm/page_ext.c |
65 | index XXXXXXX..XXXXXXX 100644 | 67 | index XXXXXXX..XXXXXXX 100644 |
... | ... | diff view generated by jsdifflib |