... | ... | ||
---|---|---|---|
7 | NUMA nodes based on their performance weight, thereby optimizing memory | 7 | NUMA nodes based on their performance weight, thereby optimizing memory |
8 | bandwidth utilization. The weight values are configured through sysfs. | 8 | bandwidth utilization. The weight values are configured through sysfs. |
9 | 9 | ||
10 | Previously, sysfs entries for weighted interleave were managed statically | 10 | Previously, sysfs entries for weighted interleave were managed statically |
11 | at initialization. This led to several issues: | 11 | at initialization. This led to several issues: |
12 | - Memory Leaks: Improper `kobject` deallocation caused memory leaks | 12 | - Memory Leaks: Improper `kobject` teardown caused memory leaks |
13 | when initialization failed or when nodes were removed. | 13 | when initialization failed or when nodes were removed. |
14 | - Lack of Dynamic Updates: Sysfs attributes were created only during | 14 | - Lack of Dynamic Updates: Sysfs attributes were created only during |
15 | initialization, preventing nodes added at runtime from being recognized. | 15 | initialization, preventing nodes added at runtime from being recognized. |
16 | - Handling of Unusable Nodes: Sysfs entries were generated for all | 16 | - Handling of Unusable Nodes: Sysfs entries were generated for all |
17 | possible nodes (`N_POSSIBLE`), including memoryless or unavailable nodes, | 17 | possible nodes (`N_POSSIBLE`), including memoryless or unavailable nodes, |
18 | leading to sysfs entries for unusable nodes and potential | 18 | leading to sysfs entries for unusable nodes and potential |
19 | misconfigurations. | 19 | misconfigurations. |
20 | 20 | ||
21 | ### Patch Overview | 21 | ### Patch Overview |
22 | 1. [PATCH 1/3] Fix memory leaks in weighted interleave sysfs | 22 | 1. [PATCH 1/3] mm/mempolicy: Fix memory leaks in weighted interleave sysfs |
23 | - Ensures proper cleanup of `kobject` allocations. | 23 | - Ensures proper cleanup of `kobject` allocations. |
24 | - Replaces unnecessary `kfree()` calls with `kobject_put()`, preventing | 24 | - Adds `kobject_del()` before `kobject_put()` to clean up sysfs state correctly. |
25 | memory leaks and improving system stability. | 25 | - Prevents memory/resource leaks and improves teardown behavior. |
26 | 26 | ||
27 | 2. [PATCH 2/3] Enable dynamic updates for weighted interleave sysfs | 27 | 2. [PATCH 2/3] mm/mempolicy: Prepare weighted interleave sysfs for memory hotplug |
28 | - Restructures sysfs handling to allow runtime updates. | 28 | - Refactors static sysfs layout into a new `sysfs_wi_group` structure. |
29 | - The sysfs attributes are now globally accessible, enabling external | 29 | - Makes per-node sysfs attributes accessible to external modules. |
30 | modules to manage interleave settings dynamically. | 30 | - Lays groundwork for future hotplug support by enabling runtime modification. |
31 | 31 | ||
32 | 3. [PATCH 3/3] Support memory hotplug in weighted interleave | 32 | 3. [PATCH 3/3] mm/mempolicy: Support memory hotplug in weighted interleave |
33 | - Modifies sysfs creation logic to restrict entries to nodes that are | 33 | - Dynamically adds/removes sysfs entries when nodes are online/offline. |
34 | online and have memory, excluding unusable nodes. | 34 | - Limits sysfs creation to nodes with memory, avoiding unusable node entries. |
35 | - Introduces a memory hotplug mechanism to dynamically add and remove | 35 | - Hooks into memory hotplug notifier for runtime updates. |
36 | sysfs attributes when nodes transition into or out of the `N_MEMORY` set. | ||
37 | - Ensures that sysfs attributes are properly removed when nodes go offline, | ||
38 | preventing stale or redundant entries from persisting. | ||
39 | 36 | ||
40 | These patches have been tested under CXL-based memory configurations, | 37 | These patches have been tested under CXL-based memory configurations, |
41 | including hotplug scenarios, to ensure proper behavior and stability. | 38 | including hotplug scenarios, to ensure proper behavior and stability. |
42 | 39 | ||
43 | mm/mempolicy.c | 195 ++++++++++++++++++++++++++++++++----------------- | 40 | mm/mempolicy.c | 194 ++++++++++++++++++++++++++++++++----------------- |
44 | 1 file changed, 127 insertions(+), 68 deletions(-) | 41 | 1 file changed, 126 insertions(+), 68 deletions(-) |
45 | 42 | ||
46 | 43 | ||
47 | base-commit: 38fec10eb60d687e30c8c6b5420d86e8149f7557 | 44 | base-commit: 38fec10eb60d687e30c8c6b5420d86e8149f7557 |
48 | -- | 45 | -- |
49 | 2.34.1 | 46 | 2.34.1 | diff view generated by jsdifflib |
1 | Memory leaks occurred when removing sysfs attributes for weighted | 1 | Memory leaks occurred when removing sysfs attributes for weighted |
---|---|---|---|
2 | interleave. Improper kobject deallocation led to unreleased memory | 2 | interleave. Improper kobject deallocation led to unreleased memory |
3 | when initialization failed or when nodes were removed. | 3 | when initialization failed or when nodes were removed. |
4 | 4 | ||
5 | This patch resolves the issue by replacing unnecessary `kfree()` | 5 | This patch resolves the issue by replacing unnecessary `kfree()` |
6 | calls with `kobject_put()`, ensuring proper cleanup and preventing | 6 | calls with proper `kobject_del()` and `kobject_put()` sequences, |
7 | memory leaks. | 7 | ensuring correct teardown and preventing memory leaks. |
8 | 8 | ||
9 | By correctly using `kobject_put()`, the release function now | 9 | By explicitly calling `kobject_del()` before `kobject_put()`, |
10 | properly deallocates memory without causing resource leaks, | 10 | the release function is now invoked safely, and internal sysfs |
11 | thereby improving system stability. | 11 | state is correctly cleaned up. This guarantees that the memory |
12 | associated with the kobject is fully released and avoids | ||
13 | resource leaks, thereby improving system stability. | ||
12 | 14 | ||
13 | Fixes: dce41f5ae253 ("mm/mempolicy: implement the sysfs-based weighted_interleave interface") | 15 | Fixes: dce41f5ae253 ("mm/mempolicy: implement the sysfs-based weighted_interleave interface") |
14 | Signed-off-by: Rakie Kim <rakie.kim@sk.com> | 16 | Signed-off-by: Rakie Kim <rakie.kim@sk.com> |
15 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> | 17 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> |
16 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> | 18 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> |
17 | Reviewed-by: Gregory Price <gourry@gourry.net> | 19 | Reviewed-by: Gregory Price <gourry@gourry.net> |
18 | --- | 20 | --- |
19 | mm/mempolicy.c | 61 +++++++++++++++++++++++++------------------------- | 21 | mm/mempolicy.c | 64 +++++++++++++++++++++++++++----------------------- |
20 | 1 file changed, 31 insertions(+), 30 deletions(-) | 22 | 1 file changed, 34 insertions(+), 30 deletions(-) |
21 | 23 | ||
22 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | 24 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
23 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/mm/mempolicy.c | 26 | --- a/mm/mempolicy.c |
25 | +++ b/mm/mempolicy.c | 27 | +++ b/mm/mempolicy.c |
... | ... | ||
65 | break; | 67 | break; |
66 | } | 68 | } |
67 | } | 69 | } |
68 | - if (err) | 70 | - if (err) |
69 | + if (err) { | 71 | + if (err) { |
72 | + kobject_del(wi_kobj); | ||
70 | kobject_put(wi_kobj); | 73 | kobject_put(wi_kobj); |
71 | + goto err_out; | 74 | + goto err_out; |
72 | + } | 75 | + } |
73 | + | 76 | + |
74 | return 0; | 77 | return 0; |
... | ... | ||
117 | - pr_err("mempolicy sysfs structure failed to initialize\n"); | 120 | - pr_err("mempolicy sysfs structure failed to initialize\n"); |
118 | - kobject_put(mempolicy_kobj); | 121 | - kobject_put(mempolicy_kobj); |
119 | - return err; | 122 | - return err; |
120 | - } | 123 | - } |
121 | + if (err) | 124 | + if (err) |
122 | + goto err_out; | 125 | + goto err_del; |
123 | + | ||
124 | + return 0; | ||
125 | 126 | ||
126 | - return err; | 127 | - return err; |
127 | -node_out: | 128 | -node_out: |
128 | - kfree(node_attrs); | 129 | - kfree(node_attrs); |
129 | -mempol_out: | 130 | -mempol_out: |
130 | - kfree(mempolicy_kobj); | 131 | - kfree(mempolicy_kobj); |
132 | + return 0; | ||
133 | + | ||
134 | +err_del: | ||
135 | + kobject_del(mempolicy_kobj); | ||
131 | err_out: | 136 | err_out: |
132 | - pr_err("failed to add mempolicy kobject to the system\n"); | 137 | - pr_err("failed to add mempolicy kobject to the system\n"); |
133 | + kobject_put(mempolicy_kobj); | 138 | + kobject_put(mempolicy_kobj); |
134 | return err; | 139 | return err; |
135 | } | 140 | } |
136 | 141 | ||
137 | -- | 142 | -- |
138 | 2.34.1 | 143 | 2.34.1 | diff view generated by jsdifflib |
1 | Previously, the weighted interleave sysfs structure was statically | 1 | Previously, the weighted interleave sysfs structure was statically |
---|---|---|---|
2 | managed, preventing dynamic updates when nodes were added or removed. | 2 | managed during initialization. This prevented new nodes from being |
3 | recognized when memory hotplug events occurred, limiting the ability | ||
4 | to update or extend sysfs entries dynamically at runtime. | ||
3 | 5 | ||
4 | This patch restructures the weighted interleave sysfs to support | 6 | To address this, this patch refactors the sysfs infrastructure and |
5 | dynamic insertion and deletion. The sysfs that was part of | 7 | encapsulates it within a new structure, `sysfs_wi_group`, which holds |
6 | the 'weighted_interleave_group' is now globally accessible, | 8 | both the kobject and an array of node attribute pointers. |
7 | allowing external access to that sysfs. | ||
8 | 9 | ||
9 | With this change, sysfs management for weighted interleave is | 10 | By allocating this group structure globally, the per-node sysfs |
10 | more flexible, supporting hotplug events and runtime updates | 11 | attributes can be managed beyond initialization time, enabling |
11 | more effectively. | 12 | external modules to insert or remove node entries in response to |
13 | events such as memory hotplug or node online/offline transitions. | ||
14 | |||
15 | Instead of allocating all per-node sysfs attributes at once, the | ||
16 | initialization path now uses the existing sysfs_wi_node_add() and | ||
17 | sysfs_wi_node_delete() helpers. This refactoring makes it possible | ||
18 | to modularly manage per-node sysfs entries and ensures the | ||
19 | infrastructure is ready for runtime extension. | ||
12 | 20 | ||
13 | Signed-off-by: Rakie Kim <rakie.kim@sk.com> | 21 | Signed-off-by: Rakie Kim <rakie.kim@sk.com> |
14 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> | 22 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> |
15 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> | 23 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> |
16 | Reviewed-by: Gregory Price <gourry@gourry.net> | 24 | Reviewed-by: Gregory Price <gourry@gourry.net> |
17 | --- | 25 | --- |
18 | mm/mempolicy.c | 71 ++++++++++++++++++++++---------------------------- | 26 | mm/mempolicy.c | 73 ++++++++++++++++++++++---------------------------- |
19 | 1 file changed, 31 insertions(+), 40 deletions(-) | 27 | 1 file changed, 32 insertions(+), 41 deletions(-) |
20 | 28 | ||
21 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | 29 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
22 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/mm/mempolicy.c | 31 | --- a/mm/mempolicy.c |
24 | +++ b/mm/mempolicy.c | 32 | +++ b/mm/mempolicy.c |
... | ... | ||
42 | 50 | ||
43 | -static struct iw_node_attr **node_attrs; | 51 | -static struct iw_node_attr **node_attrs; |
44 | - | 52 | - |
45 | -static void sysfs_wi_node_release(struct iw_node_attr *node_attr, | 53 | -static void sysfs_wi_node_release(struct iw_node_attr *node_attr, |
46 | - struct kobject *parent) | 54 | - struct kobject *parent) |
47 | +static void sysfs_wi_node_release(int nid) | 55 | +static void sysfs_wi_node_delete(int nid) |
48 | { | 56 | { |
49 | - if (!node_attr) | 57 | - if (!node_attr) |
50 | + if (!wi_group->nattrs[nid]) | 58 | + if (!wi_group->nattrs[nid]) |
51 | return; | 59 | return; |
52 | - sysfs_remove_file(parent, &node_attr->kobj_attr.attr); | 60 | - sysfs_remove_file(parent, &node_attr->kobj_attr.attr); |
... | ... | ||
68 | + int nid; | 76 | + int nid; |
69 | 77 | ||
70 | - kfree(node_attrs); | 78 | - kfree(node_attrs); |
71 | - kfree(wi_kobj); | 79 | - kfree(wi_kobj); |
72 | + for (nid = 0; nid < nr_node_ids; nid++) | 80 | + for (nid = 0; nid < nr_node_ids; nid++) |
73 | + sysfs_wi_node_release(nid); | 81 | + sysfs_wi_node_delete(nid); |
74 | + kfree(wi_group); | 82 | + kfree(wi_group); |
75 | } | 83 | } |
76 | 84 | ||
77 | static const struct kobj_type wi_ktype = { | 85 | static const struct kobj_type wi_ktype = { |
78 | @@ -XXX,XX +XXX,XX @@ static const struct kobj_type wi_ktype = { | 86 | @@ -XXX,XX +XXX,XX @@ static const struct kobj_type wi_ktype = { |
... | ... | ||
108 | int nid, err; | 116 | int nid, err; |
109 | 117 | ||
110 | - node_attrs = kcalloc(nr_node_ids, sizeof(struct iw_node_attr *), | 118 | - node_attrs = kcalloc(nr_node_ids, sizeof(struct iw_node_attr *), |
111 | - GFP_KERNEL); | 119 | - GFP_KERNEL); |
112 | - if (!node_attrs) | 120 | - if (!node_attrs) |
113 | + wi_group = kzalloc(sizeof(struct sysfs_wi_group) + \ | 121 | + wi_group = kzalloc(struct_size(wi_group, nattrs, nr_node_ids), |
114 | + nr_node_ids * sizeof(struct iw_node_attr *), \ | 122 | + GFP_KERNEL); |
115 | + GFP_KERNEL); | ||
116 | + if (!wi_group) | 123 | + if (!wi_group) |
117 | return -ENOMEM; | 124 | return -ENOMEM; |
118 | 125 | ||
119 | - wi_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); | 126 | - wi_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); |
120 | - if (!wi_kobj) { | 127 | - if (!wi_kobj) { |
... | ... | ||
135 | - err = add_weight_node(nid, wi_kobj); | 142 | - err = add_weight_node(nid, wi_kobj); |
136 | + err = sysfs_wi_node_add(nid); | 143 | + err = sysfs_wi_node_add(nid); |
137 | if (err) { | 144 | if (err) { |
138 | pr_err("failed to add sysfs [node%d]\n", nid); | 145 | pr_err("failed to add sysfs [node%d]\n", nid); |
139 | - break; | 146 | - break; |
140 | + goto err_out; | 147 | + goto err_del; |
141 | } | 148 | } |
142 | } | 149 | } |
143 | - if (err) { | 150 | - if (err) { |
151 | - kobject_del(wi_kobj); | ||
144 | - kobject_put(wi_kobj); | 152 | - kobject_put(wi_kobj); |
145 | - goto err_out; | 153 | - goto err_out; |
146 | - } | 154 | - } |
147 | 155 | ||
148 | return 0; | 156 | return 0; |
149 | 157 | ||
150 | -node_out: | 158 | -node_out: |
151 | - kfree(node_attrs); | 159 | - kfree(node_attrs); |
160 | +err_del: | ||
161 | + kobject_del(&wi_group->wi_kobj); | ||
152 | err_out: | 162 | err_out: |
153 | + kobject_put(&wi_group->wi_kobj); | 163 | + kobject_put(&wi_group->wi_kobj); |
154 | return err; | 164 | return err; |
155 | } | 165 | } |
156 | 166 | ||
157 | -- | 167 | -- |
158 | 2.34.1 | 168 | 2.34.1 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
27 | 27 | ||
28 | Signed-off-by: Rakie Kim <rakie.kim@sk.com> | 28 | Signed-off-by: Rakie Kim <rakie.kim@sk.com> |
29 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> | 29 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> |
30 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> | 30 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> |
31 | --- | 31 | --- |
32 | mm/mempolicy.c | 113 +++++++++++++++++++++++++++++++++++++++---------- | 32 | mm/mempolicy.c | 109 ++++++++++++++++++++++++++++++++++++++----------- |
33 | 1 file changed, 90 insertions(+), 23 deletions(-) | 33 | 1 file changed, 86 insertions(+), 23 deletions(-) |
34 | 34 | ||
35 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | 35 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
36 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
37 | --- a/mm/mempolicy.c | 37 | --- a/mm/mempolicy.c |
38 | +++ b/mm/mempolicy.c | 38 | +++ b/mm/mempolicy.c |
... | ... | ||
52 | struct iw_node_attr *nattrs[]; | 52 | struct iw_node_attr *nattrs[]; |
53 | }; | 53 | }; |
54 | 54 | ||
55 | @@ -XXX,XX +XXX,XX @@ static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr, | 55 | @@ -XXX,XX +XXX,XX @@ static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr, |
56 | 56 | ||
57 | static void sysfs_wi_node_release(int nid) | 57 | static void sysfs_wi_node_delete(int nid) |
58 | { | 58 | { |
59 | - if (!wi_group->nattrs[nid]) | 59 | - if (!wi_group->nattrs[nid]) |
60 | + struct iw_node_attr *attr; | 60 | + struct iw_node_attr *attr; |
61 | + | 61 | + |
62 | + if (nid < 0 || nid >= nr_node_ids) | 62 | + if (nid < 0 || nid >= nr_node_ids) |
... | ... | ||
66 | + attr = wi_group->nattrs[nid]; | 66 | + attr = wi_group->nattrs[nid]; |
67 | + if (!attr) { | 67 | + if (!attr) { |
68 | + mutex_unlock(&wi_group->kobj_lock); | 68 | + mutex_unlock(&wi_group->kobj_lock); |
69 | return; | 69 | return; |
70 | + } | 70 | + } |
71 | + | ||
72 | + wi_group->nattrs[nid] = NULL; | ||
73 | + mutex_unlock(&wi_group->kobj_lock); | ||
71 | 74 | ||
72 | - sysfs_remove_file(&wi_group->wi_kobj, | 75 | - sysfs_remove_file(&wi_group->wi_kobj, |
73 | - &wi_group->nattrs[nid]->kobj_attr.attr); | 76 | - &wi_group->nattrs[nid]->kobj_attr.attr); |
74 | - kfree(wi_group->nattrs[nid]->kobj_attr.attr.name); | 77 | - kfree(wi_group->nattrs[nid]->kobj_attr.attr.name); |
75 | - kfree(wi_group->nattrs[nid]); | 78 | - kfree(wi_group->nattrs[nid]); |
76 | + wi_group->nattrs[nid] = NULL; | ||
77 | + mutex_unlock(&wi_group->kobj_lock); | ||
78 | + | ||
79 | + sysfs_remove_file(&wi_group->wi_kobj, &attr->kobj_attr.attr); | 79 | + sysfs_remove_file(&wi_group->wi_kobj, &attr->kobj_attr.attr); |
80 | + kfree(attr->kobj_attr.attr.name); | 80 | + kfree(attr->kobj_attr.attr.name); |
81 | + kfree(attr); | 81 | + kfree(attr); |
82 | } | 82 | } |
83 | 83 | ||
... | ... | ||
121 | + pr_info("Node [%d] already exists\n", nid); | 121 | + pr_info("Node [%d] already exists\n", nid); |
122 | + kfree(new_attr); | 122 | + kfree(new_attr); |
123 | + kfree(name); | 123 | + kfree(name); |
124 | + return 0; | 124 | + return 0; |
125 | + } | 125 | + } |
126 | + wi_group->nattrs[nid] = new_attr; | ||
126 | 127 | ||
127 | - if (sysfs_create_file(&wi_group->wi_kobj, &node_attr->kobj_attr.attr)) { | 128 | - if (sysfs_create_file(&wi_group->wi_kobj, &node_attr->kobj_attr.attr)) { |
128 | - kfree(node_attr->kobj_attr.attr.name); | 129 | - kfree(node_attr->kobj_attr.attr.name); |
129 | - kfree(node_attr); | 130 | - kfree(node_attr); |
130 | - pr_err("failed to add attribute to weighted_interleave\n"); | 131 | - pr_err("failed to add attribute to weighted_interleave\n"); |
131 | - return -ENOMEM; | 132 | - return -ENOMEM; |
132 | + wi_group->nattrs[nid] = new_attr; | ||
133 | + mutex_unlock(&wi_group->kobj_lock); | ||
134 | + | ||
135 | + sysfs_attr_init(&wi_group->nattrs[nid]->kobj_attr.attr); | 133 | + sysfs_attr_init(&wi_group->nattrs[nid]->kobj_attr.attr); |
136 | + wi_group->nattrs[nid]->kobj_attr.attr.name = name; | 134 | + wi_group->nattrs[nid]->kobj_attr.attr.name = name; |
137 | + wi_group->nattrs[nid]->kobj_attr.attr.mode = 0644; | 135 | + wi_group->nattrs[nid]->kobj_attr.attr.mode = 0644; |
138 | + wi_group->nattrs[nid]->kobj_attr.show = node_show; | 136 | + wi_group->nattrs[nid]->kobj_attr.show = node_show; |
139 | + wi_group->nattrs[nid]->kobj_attr.store = node_store; | 137 | + wi_group->nattrs[nid]->kobj_attr.store = node_store; |
... | ... | ||
145 | + kfree(wi_group->nattrs[nid]->kobj_attr.attr.name); | 143 | + kfree(wi_group->nattrs[nid]->kobj_attr.attr.name); |
146 | + kfree(wi_group->nattrs[nid]); | 144 | + kfree(wi_group->nattrs[nid]); |
147 | + wi_group->nattrs[nid] = NULL; | 145 | + wi_group->nattrs[nid] = NULL; |
148 | + pr_err("Failed to add attribute to weighted_interleave: %d\n", ret); | 146 | + pr_err("Failed to add attribute to weighted_interleave: %d\n", ret); |
149 | } | 147 | } |
148 | + mutex_unlock(&wi_group->kobj_lock); | ||
150 | 149 | ||
151 | - wi_group->nattrs[nid] = node_attr; | 150 | - wi_group->nattrs[nid] = node_attr; |
152 | - return 0; | 151 | - return 0; |
153 | + return ret; | 152 | + return ret; |
154 | +} | 153 | +} |
... | ... | ||
163 | + if (nid < 0) | 162 | + if (nid < 0) |
164 | + goto notifier_end; | 163 | + goto notifier_end; |
165 | + | 164 | + |
166 | + switch(action) { | 165 | + switch(action) { |
167 | + case MEM_ONLINE: | 166 | + case MEM_ONLINE: |
168 | + if (node_state(nid, N_MEMORY)) { | 167 | + err = sysfs_wi_node_add(nid); |
169 | + err = sysfs_wi_node_add(nid); | 168 | + if (err) { |
170 | + if (err) { | 169 | + pr_err("failed to add sysfs [node%d]\n", nid); |
171 | + pr_err("failed to add sysfs [node%d]\n", nid); | 170 | + return NOTIFY_BAD; |
172 | + return NOTIFY_BAD; | ||
173 | + } | ||
174 | + } | 171 | + } |
175 | + break; | 172 | + break; |
176 | + case MEM_OFFLINE: | 173 | + case MEM_OFFLINE: |
177 | + if (!node_state(nid, N_MEMORY)) | 174 | + sysfs_wi_node_delete(nid); |
178 | + sysfs_wi_node_release(nid); | ||
179 | + break; | 175 | + break; |
180 | + } | 176 | + } |
181 | + | 177 | + |
182 | +notifier_end: | 178 | +notifier_end: |
183 | + return NOTIFY_OK; | 179 | + return NOTIFY_OK; |
184 | } | 180 | } |
185 | 181 | ||
186 | static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) | 182 | static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) |
187 | @@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) | 183 | @@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) |
188 | GFP_KERNEL); | 184 | GFP_KERNEL); |
189 | if (!wi_group) | 185 | if (!wi_group) |
190 | return -ENOMEM; | 186 | return -ENOMEM; |
191 | + mutex_init(&wi_group->kobj_lock); | 187 | + mutex_init(&wi_group->kobj_lock); |
192 | 188 | ||
193 | err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj, | 189 | err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj, |
... | ... | ||
208 | } | 204 | } |
209 | 205 | ||
210 | + hotplug_memory_notifier(wi_node_notifier, DEFAULT_CALLBACK_PRI); | 206 | + hotplug_memory_notifier(wi_node_notifier, DEFAULT_CALLBACK_PRI); |
211 | return 0; | 207 | return 0; |
212 | 208 | ||
213 | err_out: | 209 | err_del: |
214 | -- | 210 | -- |
215 | 2.34.1 | 211 | 2.34.1 | diff view generated by jsdifflib |