... | ... | ||
---|---|---|---|
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 unnecessary sysfs attributes and misconfiguration issues. | 18 | leading to sysfs entries for unusable nodes and potential |
19 | misconfigurations. | ||
19 | 20 | ||
20 | ### Patch Overview | 21 | ### Patch Overview |
21 | 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 |
22 | - Ensures proper cleanup of `kobject` allocations. | 23 | - Ensures proper cleanup of `kobject` allocations. |
23 | - Replaces unnecessary `kfree()` calls with `kobject_put()`, preventing | 24 | - Adds `kobject_del()` before `kobject_put()` to clean up sysfs state correctly. |
24 | memory leaks and improving system stability. | 25 | - Prevents memory/resource leaks and improves teardown behavior. |
25 | 26 | ||
26 | 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 |
27 | - Restructures sysfs handling to allow runtime updates. | 28 | - Refactors static sysfs layout into a new `sysfs_wi_group` structure. |
28 | - The sysfs attributes are now globally accessible, enabling external | 29 | - Makes per-node sysfs attributes accessible to external modules. |
29 | modules to manage interleave settings dynamically. | 30 | - Lays groundwork for future hotplug support by enabling runtime modification. |
30 | 31 | ||
31 | 3. [PATCH 3/3] Support memory hotplug in weighted interleave | 32 | 3. [PATCH 3/3] mm/mempolicy: Support memory hotplug in weighted interleave |
32 | - Modifies sysfs creation logic to restrict entries to nodes that are | 33 | - Dynamically adds/removes sysfs entries when nodes are online/offline. |
33 | online and have memory, excluding unusable nodes. | 34 | - Limits sysfs creation to nodes with memory, avoiding unusable node entries. |
34 | - Introduces a memory hotplug mechanism to dynamically add and remove | 35 | - Hooks into memory hotplug notifier for runtime updates. |
35 | sysfs attributes when nodes transition into or out of the `N_MEMORY` set. | ||
36 | - Ensures that sysfs attributes are properly removed when nodes go offline, | ||
37 | preventing stale or redundant entries from persisting. | ||
38 | 36 | ||
39 | These patches have been tested under CXL-based memory configurations, | 37 | These patches have been tested under CXL-based memory configurations, |
40 | including hotplug scenarios, to ensure proper behavior and stability. | 38 | including hotplug scenarios, to ensure proper behavior and stability. |
41 | 39 | ||
42 | mm/mempolicy.c | 191 +++++++++++++++++++++++++++++++------------------ | 40 | mm/mempolicy.c | 194 ++++++++++++++++++++++++++++++++----------------- |
43 | 1 file changed, 123 insertions(+), 68 deletions(-) | 41 | 1 file changed, 126 insertions(+), 68 deletions(-) |
44 | 42 | ||
45 | 43 | ||
46 | base-commit: 4701f33a10702d5fc577c32434eb62adde0a1ae1 | 44 | base-commit: 38fec10eb60d687e30c8c6b5420d86e8149f7557 |
47 | -- | 45 | -- |
48 | 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> |
17 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> | ||
18 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> | ||
19 | Reviewed-by: Gregory Price <gourry@gourry.net> | ||
15 | --- | 20 | --- |
16 | mm/mempolicy.c | 61 +++++++++++++++++++++++++------------------------- | 21 | mm/mempolicy.c | 64 +++++++++++++++++++++++++++----------------------- |
17 | 1 file changed, 31 insertions(+), 30 deletions(-) | 22 | 1 file changed, 34 insertions(+), 30 deletions(-) |
18 | 23 | ||
19 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | 24 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
20 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/mm/mempolicy.c | 26 | --- a/mm/mempolicy.c |
22 | +++ b/mm/mempolicy.c | 27 | +++ b/mm/mempolicy.c |
... | ... | ||
62 | break; | 67 | break; |
63 | } | 68 | } |
64 | } | 69 | } |
65 | - if (err) | 70 | - if (err) |
66 | + if (err) { | 71 | + if (err) { |
72 | + kobject_del(wi_kobj); | ||
67 | kobject_put(wi_kobj); | 73 | kobject_put(wi_kobj); |
68 | + goto err_out; | 74 | + goto err_out; |
69 | + } | 75 | + } |
70 | + | 76 | + |
71 | return 0; | 77 | return 0; |
... | ... | ||
114 | - pr_err("mempolicy sysfs structure failed to initialize\n"); | 120 | - pr_err("mempolicy sysfs structure failed to initialize\n"); |
115 | - kobject_put(mempolicy_kobj); | 121 | - kobject_put(mempolicy_kobj); |
116 | - return err; | 122 | - return err; |
117 | - } | 123 | - } |
118 | + if (err) | 124 | + if (err) |
119 | + goto err_out; | 125 | + goto err_del; |
120 | + | ||
121 | + return 0; | ||
122 | 126 | ||
123 | - return err; | 127 | - return err; |
124 | -node_out: | 128 | -node_out: |
125 | - kfree(node_attrs); | 129 | - kfree(node_attrs); |
126 | -mempol_out: | 130 | -mempol_out: |
127 | - kfree(mempolicy_kobj); | 131 | - kfree(mempolicy_kobj); |
132 | + return 0; | ||
133 | + | ||
134 | +err_del: | ||
135 | + kobject_del(mempolicy_kobj); | ||
128 | err_out: | 136 | err_out: |
129 | - pr_err("failed to add mempolicy kobject to the system\n"); | 137 | - pr_err("failed to add mempolicy kobject to the system\n"); |
130 | + kobject_put(mempolicy_kobj); | 138 | + kobject_put(mempolicy_kobj); |
131 | return err; | 139 | return err; |
132 | } | 140 | } |
133 | 141 | ||
134 | |||
135 | base-commit: 4701f33a10702d5fc577c32434eb62adde0a1ae1 | ||
136 | -- | 142 | -- |
137 | 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> |
22 | Signed-off-by: Honggyu Kim <honggyu.kim@sk.com> | ||
23 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> | ||
24 | Reviewed-by: Gregory Price <gourry@gourry.net> | ||
14 | --- | 25 | --- |
15 | mm/mempolicy.c | 70 ++++++++++++++++++++++---------------------------- | 26 | mm/mempolicy.c | 73 ++++++++++++++++++++++---------------------------- |
16 | 1 file changed, 30 insertions(+), 40 deletions(-) | 27 | 1 file changed, 32 insertions(+), 41 deletions(-) |
17 | 28 | ||
18 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | 29 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
19 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/mm/mempolicy.c | 31 | --- a/mm/mempolicy.c |
21 | +++ b/mm/mempolicy.c | 32 | +++ b/mm/mempolicy.c |
... | ... | ||
26 | +struct sysfs_wi_group { | 37 | +struct sysfs_wi_group { |
27 | + struct kobject wi_kobj; | 38 | + struct kobject wi_kobj; |
28 | + struct iw_node_attr *nattrs[]; | 39 | + struct iw_node_attr *nattrs[]; |
29 | +}; | 40 | +}; |
30 | + | 41 | + |
31 | +static struct sysfs_wi_group *sgrp; | 42 | +static struct sysfs_wi_group *wi_group; |
32 | + | 43 | + |
33 | static ssize_t node_show(struct kobject *kobj, struct kobj_attribute *attr, | 44 | static ssize_t node_show(struct kobject *kobj, struct kobj_attribute *attr, |
34 | char *buf) | 45 | char *buf) |
35 | { | 46 | { |
36 | @@ -XXX,XX +XXX,XX @@ static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr, | 47 | @@ -XXX,XX +XXX,XX @@ static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr, |
... | ... | ||
39 | 50 | ||
40 | -static struct iw_node_attr **node_attrs; | 51 | -static struct iw_node_attr **node_attrs; |
41 | - | 52 | - |
42 | -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, |
43 | - struct kobject *parent) | 54 | - struct kobject *parent) |
44 | +static void sysfs_wi_node_release(int nid) | 55 | +static void sysfs_wi_node_delete(int nid) |
45 | { | 56 | { |
46 | - if (!node_attr) | 57 | - if (!node_attr) |
47 | + if (!sgrp->nattrs[nid]) | 58 | + if (!wi_group->nattrs[nid]) |
48 | return; | 59 | return; |
49 | - sysfs_remove_file(parent, &node_attr->kobj_attr.attr); | 60 | - sysfs_remove_file(parent, &node_attr->kobj_attr.attr); |
50 | - kfree(node_attr->kobj_attr.attr.name); | 61 | - kfree(node_attr->kobj_attr.attr.name); |
51 | - kfree(node_attr); | 62 | - kfree(node_attr); |
52 | + | 63 | + |
53 | + sysfs_remove_file(&sgrp->wi_kobj, &sgrp->nattrs[nid]->kobj_attr.attr); | 64 | + sysfs_remove_file(&wi_group->wi_kobj, |
54 | + kfree(sgrp->nattrs[nid]->kobj_attr.attr.name); | 65 | + &wi_group->nattrs[nid]->kobj_attr.attr); |
55 | + kfree(sgrp->nattrs[nid]); | 66 | + kfree(wi_group->nattrs[nid]->kobj_attr.attr.name); |
67 | + kfree(wi_group->nattrs[nid]); | ||
56 | } | 68 | } |
57 | 69 | ||
58 | static void sysfs_wi_release(struct kobject *wi_kobj) | 70 | static void sysfs_wi_release(struct kobject *wi_kobj) |
59 | { | 71 | { |
60 | - int i; | 72 | - int i; |
... | ... | ||
64 | + int nid; | 76 | + int nid; |
65 | 77 | ||
66 | - kfree(node_attrs); | 78 | - kfree(node_attrs); |
67 | - kfree(wi_kobj); | 79 | - kfree(wi_kobj); |
68 | + for (nid = 0; nid < nr_node_ids; nid++) | 80 | + for (nid = 0; nid < nr_node_ids; nid++) |
69 | + sysfs_wi_node_release(nid); | 81 | + sysfs_wi_node_delete(nid); |
70 | + kfree(sgrp); | 82 | + kfree(wi_group); |
71 | } | 83 | } |
72 | 84 | ||
73 | static const struct kobj_type wi_ktype = { | 85 | static const struct kobj_type wi_ktype = { |
74 | @@ -XXX,XX +XXX,XX @@ static const struct kobj_type wi_ktype = { | 86 | @@ -XXX,XX +XXX,XX @@ static const struct kobj_type wi_ktype = { |
75 | .release = sysfs_wi_release, | 87 | .release = sysfs_wi_release, |
... | ... | ||
83 | @@ -XXX,XX +XXX,XX @@ static int add_weight_node(int nid, struct kobject *wi_kobj) | 95 | @@ -XXX,XX +XXX,XX @@ static int add_weight_node(int nid, struct kobject *wi_kobj) |
84 | node_attr->kobj_attr.store = node_store; | 96 | node_attr->kobj_attr.store = node_store; |
85 | node_attr->nid = nid; | 97 | node_attr->nid = nid; |
86 | 98 | ||
87 | - if (sysfs_create_file(wi_kobj, &node_attr->kobj_attr.attr)) { | 99 | - if (sysfs_create_file(wi_kobj, &node_attr->kobj_attr.attr)) { |
88 | + if (sysfs_create_file(&sgrp->wi_kobj, &node_attr->kobj_attr.attr)) { | 100 | + if (sysfs_create_file(&wi_group->wi_kobj, &node_attr->kobj_attr.attr)) { |
89 | kfree(node_attr->kobj_attr.attr.name); | 101 | kfree(node_attr->kobj_attr.attr.name); |
90 | kfree(node_attr); | 102 | kfree(node_attr); |
91 | pr_err("failed to add attribute to weighted_interleave\n"); | 103 | pr_err("failed to add attribute to weighted_interleave\n"); |
92 | return -ENOMEM; | 104 | return -ENOMEM; |
93 | } | 105 | } |
94 | 106 | ||
95 | - node_attrs[nid] = node_attr; | 107 | - node_attrs[nid] = node_attr; |
96 | + sgrp->nattrs[nid] = node_attr; | 108 | + wi_group->nattrs[nid] = node_attr; |
97 | return 0; | 109 | return 0; |
98 | } | 110 | } |
99 | 111 | ||
100 | -static int add_weighted_interleave_group(struct kobject *root_kobj) | 112 | -static int add_weighted_interleave_group(struct kobject *root_kobj) |
101 | +static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) | 113 | +static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) |
... | ... | ||
104 | int nid, err; | 116 | int nid, err; |
105 | 117 | ||
106 | - node_attrs = kcalloc(nr_node_ids, sizeof(struct iw_node_attr *), | 118 | - node_attrs = kcalloc(nr_node_ids, sizeof(struct iw_node_attr *), |
107 | - GFP_KERNEL); | 119 | - GFP_KERNEL); |
108 | - if (!node_attrs) | 120 | - if (!node_attrs) |
109 | + sgrp = kzalloc(sizeof(struct sysfs_wi_group) + \ | 121 | + wi_group = kzalloc(struct_size(wi_group, nattrs, nr_node_ids), |
110 | + nr_node_ids * sizeof(struct iw_node_attr *), \ | 122 | + GFP_KERNEL); |
111 | + GFP_KERNEL); | 123 | + if (!wi_group) |
112 | + if (!sgrp) | ||
113 | return -ENOMEM; | 124 | return -ENOMEM; |
114 | 125 | ||
115 | - wi_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); | 126 | - wi_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); |
116 | - if (!wi_kobj) { | 127 | - if (!wi_kobj) { |
117 | - err = -ENOMEM; | 128 | - err = -ENOMEM; |
118 | - goto node_out; | 129 | - goto node_out; |
119 | - } | 130 | - } |
120 | - | 131 | - |
121 | - err = kobject_init_and_add(wi_kobj, &wi_ktype, root_kobj, | 132 | - err = kobject_init_and_add(wi_kobj, &wi_ktype, root_kobj, |
122 | + err = kobject_init_and_add(&sgrp->wi_kobj, &wi_ktype, mempolicy_kobj, | 133 | + err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj, |
123 | "weighted_interleave"); | 134 | "weighted_interleave"); |
124 | - if (err) { | 135 | - if (err) { |
125 | - kobject_put(wi_kobj); | 136 | - kobject_put(wi_kobj); |
126 | + if (err) | 137 | + if (err) |
127 | goto err_out; | 138 | goto err_out; |
... | ... | ||
131 | - err = add_weight_node(nid, wi_kobj); | 142 | - err = add_weight_node(nid, wi_kobj); |
132 | + err = sysfs_wi_node_add(nid); | 143 | + err = sysfs_wi_node_add(nid); |
133 | if (err) { | 144 | if (err) { |
134 | pr_err("failed to add sysfs [node%d]\n", nid); | 145 | pr_err("failed to add sysfs [node%d]\n", nid); |
135 | - break; | 146 | - break; |
136 | + goto err_out; | 147 | + goto err_del; |
137 | } | 148 | } |
138 | } | 149 | } |
139 | - if (err) { | 150 | - if (err) { |
151 | - kobject_del(wi_kobj); | ||
140 | - kobject_put(wi_kobj); | 152 | - kobject_put(wi_kobj); |
141 | - goto err_out; | 153 | - goto err_out; |
142 | - } | 154 | - } |
143 | 155 | ||
144 | return 0; | 156 | return 0; |
145 | 157 | ||
146 | -node_out: | 158 | -node_out: |
147 | - kfree(node_attrs); | 159 | - kfree(node_attrs); |
160 | +err_del: | ||
161 | + kobject_del(&wi_group->wi_kobj); | ||
148 | err_out: | 162 | err_out: |
149 | + kobject_put(&sgrp->wi_kobj); | 163 | + kobject_put(&wi_group->wi_kobj); |
150 | return err; | 164 | return err; |
151 | } | 165 | } |
152 | 166 | ||
153 | -- | 167 | -- |
154 | 2.34.1 | 168 | 2.34.1 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
9 | runtime, as some may remain memoryless or offline. | 9 | runtime, as some may remain memoryless or offline. |
10 | This led to sysfs entries being created for unusable nodes, causing | 10 | This led to sysfs entries being created for unusable nodes, causing |
11 | potential misconfiguration issues. | 11 | potential misconfiguration issues. |
12 | 12 | ||
13 | To address this issue, this patch modifies the sysfs creation logic to: | 13 | To address this issue, this patch modifies the sysfs creation logic to: |
14 | 1) Limit sysfs entries to nodes that are online and have memory, reducing | 14 | 1) Limit sysfs entries to nodes that are online and have memory, avoiding |
15 | the creation of sysfs attributes for unusable nodes. | 15 | the creation of sysfs entries for nodes that cannot be used. |
16 | 2) Support memory hotplug by dynamically adding and removing sysfs entries | 16 | 2) Support memory hotplug by dynamically adding and removing sysfs entries |
17 | based on whether a node transitions into or out of the N_MEMORY state. | 17 | based on whether a node transitions into or out of the N_MEMORY state. |
18 | 18 | ||
19 | Additionally, the patch ensures that sysfs attributes are properly managed | 19 | Additionally, the patch ensures that sysfs attributes are properly managed |
20 | when nodes go offline, preventing stale or redundant entries from persisting | 20 | when nodes go offline, preventing stale or redundant entries from persisting |
... | ... | ||
24 | sysfs entries more efficiently, ensuring that only relevant nodes are | 24 | sysfs entries more efficiently, ensuring that only relevant nodes are |
25 | considered for interleaving, and dynamically adapting to memory hotplug | 25 | considered for interleaving, and dynamically adapting to memory hotplug |
26 | events. | 26 | events. |
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> | ||
30 | Signed-off-by: Yunjeong Mun <yunjeong.mun@sk.com> | ||
29 | --- | 31 | --- |
30 | mm/mempolicy.c | 108 +++++++++++++++++++++++++++++++++++++++---------- | 32 | mm/mempolicy.c | 109 ++++++++++++++++++++++++++++++++++++++----------- |
31 | 1 file changed, 86 insertions(+), 22 deletions(-) | 33 | 1 file changed, 86 insertions(+), 23 deletions(-) |
32 | 34 | ||
33 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c | 35 | diff --git a/mm/mempolicy.c b/mm/mempolicy.c |
34 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
35 | --- a/mm/mempolicy.c | 37 | --- a/mm/mempolicy.c |
36 | +++ b/mm/mempolicy.c | 38 | +++ b/mm/mempolicy.c |
... | ... | ||
50 | struct iw_node_attr *nattrs[]; | 52 | struct iw_node_attr *nattrs[]; |
51 | }; | 53 | }; |
52 | 54 | ||
53 | @@ -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, |
54 | 56 | ||
55 | static void sysfs_wi_node_release(int nid) | 57 | static void sysfs_wi_node_delete(int nid) |
56 | { | 58 | { |
57 | - if (!sgrp->nattrs[nid]) | 59 | - if (!wi_group->nattrs[nid]) |
58 | + struct iw_node_attr *attr; | 60 | + struct iw_node_attr *attr; |
59 | + | 61 | + |
60 | + if (nid < 0 || nid >= nr_node_ids) | 62 | + if (nid < 0 || nid >= nr_node_ids) |
61 | + return; | 63 | + return; |
62 | + | 64 | + |
63 | + mutex_lock(&sgrp->kobj_lock); | 65 | + mutex_lock(&wi_group->kobj_lock); |
64 | + attr = sgrp->nattrs[nid]; | 66 | + attr = wi_group->nattrs[nid]; |
65 | + if (!attr) { | 67 | + if (!attr) { |
66 | + mutex_unlock(&sgrp->kobj_lock); | 68 | + mutex_unlock(&wi_group->kobj_lock); |
67 | return; | 69 | return; |
68 | + } | 70 | + } |
69 | + | 71 | + |
70 | + sgrp->nattrs[nid] = NULL; | 72 | + wi_group->nattrs[nid] = NULL; |
71 | + mutex_unlock(&sgrp->kobj_lock); | 73 | + mutex_unlock(&wi_group->kobj_lock); |
72 | 74 | ||
73 | - sysfs_remove_file(&sgrp->wi_kobj, &sgrp->nattrs[nid]->kobj_attr.attr); | 75 | - sysfs_remove_file(&wi_group->wi_kobj, |
74 | - kfree(sgrp->nattrs[nid]->kobj_attr.attr.name); | 76 | - &wi_group->nattrs[nid]->kobj_attr.attr); |
75 | - kfree(sgrp->nattrs[nid]); | 77 | - kfree(wi_group->nattrs[nid]->kobj_attr.attr.name); |
76 | + sysfs_remove_file(&sgrp->wi_kobj, &attr->kobj_attr.attr); | 78 | - kfree(wi_group->nattrs[nid]); |
79 | + sysfs_remove_file(&wi_group->wi_kobj, &attr->kobj_attr.attr); | ||
77 | + kfree(attr->kobj_attr.attr.name); | 80 | + kfree(attr->kobj_attr.attr.name); |
78 | + kfree(attr); | 81 | + kfree(attr); |
79 | } | 82 | } |
80 | 83 | ||
81 | static void sysfs_wi_release(struct kobject *wi_kobj) | 84 | static void sysfs_wi_release(struct kobject *wi_kobj) |
... | ... | ||
85 | { | 88 | { |
86 | - struct iw_node_attr *node_attr; | 89 | - struct iw_node_attr *node_attr; |
87 | + int ret = 0; | 90 | + int ret = 0; |
88 | char *name; | 91 | char *name; |
89 | + struct iw_node_attr *new_attr = NULL; | 92 | + struct iw_node_attr *new_attr = NULL; |
90 | + | 93 | |
94 | - node_attr = kzalloc(sizeof(*node_attr), GFP_KERNEL); | ||
95 | - if (!node_attr) | ||
91 | + if (nid < 0 || nid >= nr_node_ids) { | 96 | + if (nid < 0 || nid >= nr_node_ids) { |
92 | + pr_err("Invalid node id: %d\n", nid); | 97 | + pr_err("Invalid node id: %d\n", nid); |
93 | + return -EINVAL; | 98 | + return -EINVAL; |
94 | + } | 99 | + } |
95 | 100 | + | |
96 | - node_attr = kzalloc(sizeof(*node_attr), GFP_KERNEL); | ||
97 | - if (!node_attr) | ||
98 | + new_attr = kzalloc(sizeof(struct iw_node_attr), GFP_KERNEL); | 101 | + new_attr = kzalloc(sizeof(struct iw_node_attr), GFP_KERNEL); |
99 | + if (!new_attr) | 102 | + if (!new_attr) |
100 | return -ENOMEM; | 103 | return -ENOMEM; |
101 | 104 | ||
102 | name = kasprintf(GFP_KERNEL, "node%d", nid); | 105 | name = kasprintf(GFP_KERNEL, "node%d", nid); |
... | ... | ||
110 | - node_attr->kobj_attr.attr.name = name; | 113 | - node_attr->kobj_attr.attr.name = name; |
111 | - node_attr->kobj_attr.attr.mode = 0644; | 114 | - node_attr->kobj_attr.attr.mode = 0644; |
112 | - node_attr->kobj_attr.show = node_show; | 115 | - node_attr->kobj_attr.show = node_show; |
113 | - node_attr->kobj_attr.store = node_store; | 116 | - node_attr->kobj_attr.store = node_store; |
114 | - node_attr->nid = nid; | 117 | - node_attr->nid = nid; |
115 | + mutex_lock(&sgrp->kobj_lock); | 118 | + mutex_lock(&wi_group->kobj_lock); |
116 | + if (sgrp->nattrs[nid]) { | 119 | + if (wi_group->nattrs[nid]) { |
117 | + mutex_unlock(&sgrp->kobj_lock); | 120 | + mutex_unlock(&wi_group->kobj_lock); |
118 | + pr_info("Node [%d] already exists\n", nid); | 121 | + pr_info("Node [%d] already exists\n", nid); |
119 | + kfree(new_attr); | 122 | + kfree(new_attr); |
120 | + kfree(name); | 123 | + kfree(name); |
121 | + return 0; | 124 | + return 0; |
122 | + } | 125 | + } |
123 | 126 | + wi_group->nattrs[nid] = new_attr; | |
124 | - if (sysfs_create_file(&sgrp->wi_kobj, &node_attr->kobj_attr.attr)) { | 127 | |
128 | - if (sysfs_create_file(&wi_group->wi_kobj, &node_attr->kobj_attr.attr)) { | ||
125 | - kfree(node_attr->kobj_attr.attr.name); | 129 | - kfree(node_attr->kobj_attr.attr.name); |
126 | - kfree(node_attr); | 130 | - kfree(node_attr); |
127 | - pr_err("failed to add attribute to weighted_interleave\n"); | 131 | - pr_err("failed to add attribute to weighted_interleave\n"); |
128 | - return -ENOMEM; | 132 | - return -ENOMEM; |
129 | + sgrp->nattrs[nid] = new_attr; | 133 | + sysfs_attr_init(&wi_group->nattrs[nid]->kobj_attr.attr); |
130 | + mutex_unlock(&sgrp->kobj_lock); | 134 | + wi_group->nattrs[nid]->kobj_attr.attr.name = name; |
131 | + | 135 | + wi_group->nattrs[nid]->kobj_attr.attr.mode = 0644; |
132 | + sysfs_attr_init(&sgrp->nattrs[nid]->kobj_attr.attr); | 136 | + wi_group->nattrs[nid]->kobj_attr.show = node_show; |
133 | + sgrp->nattrs[nid]->kobj_attr.attr.name = name; | 137 | + wi_group->nattrs[nid]->kobj_attr.store = node_store; |
134 | + sgrp->nattrs[nid]->kobj_attr.attr.mode = 0644; | 138 | + wi_group->nattrs[nid]->nid = nid; |
135 | + sgrp->nattrs[nid]->kobj_attr.show = node_show; | 139 | + |
136 | + sgrp->nattrs[nid]->kobj_attr.store = node_store; | 140 | + ret = sysfs_create_file(&wi_group->wi_kobj, |
137 | + sgrp->nattrs[nid]->nid = nid; | 141 | + &wi_group->nattrs[nid]->kobj_attr.attr); |
138 | + | ||
139 | + ret = sysfs_create_file(&sgrp->wi_kobj, &sgrp->nattrs[nid]->kobj_attr.attr); | ||
140 | + if (ret) { | 142 | + if (ret) { |
141 | + kfree(sgrp->nattrs[nid]->kobj_attr.attr.name); | 143 | + kfree(wi_group->nattrs[nid]->kobj_attr.attr.name); |
142 | + kfree(sgrp->nattrs[nid]); | 144 | + kfree(wi_group->nattrs[nid]); |
143 | + sgrp->nattrs[nid] = NULL; | 145 | + wi_group->nattrs[nid] = NULL; |
144 | + 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); |
145 | } | 147 | } |
146 | 148 | + mutex_unlock(&wi_group->kobj_lock); | |
147 | - sgrp->nattrs[nid] = node_attr; | 149 | |
150 | - wi_group->nattrs[nid] = node_attr; | ||
148 | - return 0; | 151 | - return 0; |
149 | + return ret; | 152 | + return ret; |
150 | +} | 153 | +} |
151 | + | 154 | + |
152 | +static int wi_node_notifier(struct notifier_block *nb, | 155 | +static int wi_node_notifier(struct notifier_block *nb, |
... | ... | ||
166 | + pr_err("failed to add sysfs [node%d]\n", nid); | 169 | + pr_err("failed to add sysfs [node%d]\n", nid); |
167 | + return NOTIFY_BAD; | 170 | + return NOTIFY_BAD; |
168 | + } | 171 | + } |
169 | + break; | 172 | + break; |
170 | + case MEM_OFFLINE: | 173 | + case MEM_OFFLINE: |
171 | + sysfs_wi_node_release(nid); | 174 | + sysfs_wi_node_delete(nid); |
172 | + break; | 175 | + break; |
173 | + } | 176 | + } |
174 | + | 177 | + |
175 | +notifier_end: | 178 | +notifier_end: |
176 | + return NOTIFY_OK; | 179 | + return NOTIFY_OK; |
177 | } | 180 | } |
178 | 181 | ||
179 | static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) | 182 | static int add_weighted_interleave_group(struct kobject *mempolicy_kobj) |
180 | @@ -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) |
181 | GFP_KERNEL); | 184 | GFP_KERNEL); |
182 | if (!sgrp) | 185 | if (!wi_group) |
183 | return -ENOMEM; | 186 | return -ENOMEM; |
184 | + mutex_init(&sgrp->kobj_lock); | 187 | + mutex_init(&wi_group->kobj_lock); |
185 | 188 | ||
186 | err = kobject_init_and_add(&sgrp->wi_kobj, &wi_ktype, mempolicy_kobj, | 189 | err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj, |
187 | "weighted_interleave"); | 190 | "weighted_interleave"); |
188 | if (err) | 191 | if (err) |
189 | goto err_out; | 192 | goto err_out; |
190 | 193 | ||
191 | - for_each_node_state(nid, N_POSSIBLE) { | 194 | - for_each_node_state(nid, N_POSSIBLE) { |
... | ... | ||
201 | } | 204 | } |
202 | 205 | ||
203 | + hotplug_memory_notifier(wi_node_notifier, DEFAULT_CALLBACK_PRI); | 206 | + hotplug_memory_notifier(wi_node_notifier, DEFAULT_CALLBACK_PRI); |
204 | return 0; | 207 | return 0; |
205 | 208 | ||
206 | err_out: | 209 | err_del: |
207 | -- | 210 | -- |
208 | 2.34.1 | 211 | 2.34.1 | diff view generated by jsdifflib |