...
...
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