...
...
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 | 193 +++++++++++++++++++++++++++++++------------------
44
1 file changed, 127 insertions(+), 68 deletions(-)
41
1 file changed, 124 insertions(+), 69 deletions(-)
45
42
46
43
47
base-commit: 38fec10eb60d687e30c8c6b5420d86e8149f7557
44
base-commit: 0af2f6be1b4281385b618cb86ad946eded089ac8
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 | 66 ++++++++++++++++++++++++--------------------------
20
1 file changed, 31 insertions(+), 30 deletions(-)
22
1 file changed, 32 insertions(+), 34 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
...
...
36
static const struct kobj_type wi_ktype = {
38
static const struct kobj_type wi_ktype = {
37
@@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *root_kobj)
39
@@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *root_kobj)
38
    struct kobject *wi_kobj;
40
    struct kobject *wi_kobj;
39
    int nid, err;
41
    int nid, err;
40
42
41
-    wi_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
42
-    if (!wi_kobj)
43
+    node_attrs = kcalloc(nr_node_ids, sizeof(struct iw_node_attr *),
43
+    node_attrs = kcalloc(nr_node_ids, sizeof(struct iw_node_attr *),
44
+             GFP_KERNEL);
44
+             GFP_KERNEL);
45
+    if (!node_attrs)
45
+    if (!node_attrs)
46
+        return -ENOMEM;
47
+
48
    wi_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
49
-    if (!wi_kobj)
50
+    if (!wi_kobj) {
51
+        kfree(node_attrs);
46
        return -ENOMEM;
52
        return -ENOMEM;
47
48
+    wi_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
49
+    if (!wi_kobj) {
50
+        err = -ENOMEM;
51
+        goto node_out;
52
+    }
53
+    }
53
+
54
54
    err = kobject_init_and_add(wi_kobj, &wi_ktype, root_kobj,
55
    err = kobject_init_and_add(wi_kobj, &wi_ktype, root_kobj,
55
                 "weighted_interleave");
56
                 "weighted_interleave");
56
    if (err) {
57
-    if (err) {
57
-        kfree(wi_kobj);
58
-        kfree(wi_kobj);
58
-        return err;
59
-        return err;
59
+        kobject_put(wi_kobj);
60
-    }
60
+        goto err_out;
61
+    if (err)
61
    }
62
+        goto err_put_kobj;
62
63
63
    for_each_node_state(nid, N_POSSIBLE) {
64
    for_each_node_state(nid, N_POSSIBLE) {
64
@@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *root_kobj)
65
        err = add_weight_node(nid, wi_kobj);
65
            break;
66
        if (err) {
67
            pr_err("failed to add sysfs [node%d]\n", nid);
68
-            break;
69
+            goto err_del_kobj;
66
        }
70
        }
67
    }
71
    }
68
-    if (err)
72
-    if (err)
69
+    if (err) {
73
-        kobject_put(wi_kobj);
70
        kobject_put(wi_kobj);
71
+        goto err_out;
72
+    }
73
+
74
+
74
    return 0;
75
    return 0;
75
+
76
+
76
+node_out:
77
+err_del_kobj:
77
+    kfree(node_attrs);
78
+    kobject_del(wi_kobj);
78
+err_out:
79
+err_put_kobj:
80
+    kobject_put(wi_kobj);
79
+    return err;
81
+    return err;
80
}
82
}
81
83
82
static void mempolicy_kobj_release(struct kobject *kobj)
84
static void mempolicy_kobj_release(struct kobject *kobj)
83
@@ -XXX,XX +XXX,XX @@ static void mempolicy_kobj_release(struct kobject *kobj)
85
@@ -XXX,XX +XXX,XX @@ static void mempolicy_kobj_release(struct kobject *kobj)
...
...
108
110
109
    err = kobject_init_and_add(mempolicy_kobj, &mempolicy_ktype, mm_kobj,
111
    err = kobject_init_and_add(mempolicy_kobj, &mempolicy_ktype, mm_kobj,
110
                 "mempolicy");
112
                 "mempolicy");
111
    if (err)
113
    if (err)
112
-        goto node_out;
114
-        goto node_out;
113
+        goto err_out;
115
+        goto err_put_kobj;
114
116
115
    err = add_weighted_interleave_group(mempolicy_kobj);
117
    err = add_weighted_interleave_group(mempolicy_kobj);
116
-    if (err) {
118
-    if (err) {
117
-        pr_err("mempolicy sysfs structure failed to initialize\n");
119
-        pr_err("mempolicy sysfs structure failed to initialize\n");
118
-        kobject_put(mempolicy_kobj);
120
-        kobject_put(mempolicy_kobj);
119
-        return err;
121
-        return err;
120
-    }
122
-    }
121
+    if (err)
123
+    if (err)
122
+        goto err_out;
124
+        goto err_del_kobj;
123
+
124
+    return 0;
125
125
126
-    return err;
126
-    return err;
127
-node_out:
127
-node_out:
128
-    kfree(node_attrs);
128
-    kfree(node_attrs);
129
-mempol_out:
129
-mempol_out:
130
-    kfree(mempolicy_kobj);
130
-    kfree(mempolicy_kobj);
131
err_out:
131
-err_out:
132
-    pr_err("failed to add mempolicy kobject to the system\n");
132
-    pr_err("failed to add mempolicy kobject to the system\n");
133
+    return 0;
134
+
135
+err_del_kobj:
136
+    kobject_del(mempolicy_kobj);
137
+err_put_kobj:
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 | 61 ++++++++++++++++++++++++--------------------------
19
1 file changed, 31 insertions(+), 40 deletions(-)
27
1 file changed, 29 insertions(+), 32 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 = {
...
...
100
+    wi_group->nattrs[nid] = node_attr;
108
+    wi_group->nattrs[nid] = node_attr;
101
    return 0;
109
    return 0;
102
}
110
}
103
111
104
-static int add_weighted_interleave_group(struct kobject *root_kobj)
112
-static int add_weighted_interleave_group(struct kobject *root_kobj)
105
+static int add_weighted_interleave_group(struct kobject *mempolicy_kobj)
113
+static int __init add_weighted_interleave_group(struct kobject *mempolicy_kobj)
106
{
114
{
107
-    struct kobject *wi_kobj;
115
-    struct kobject *wi_kobj;
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) {
121
-        err = -ENOMEM;
128
-        kfree(node_attrs);
122
-        goto node_out;
129
-        return -ENOMEM;
123
-    }
130
-    }
124
-
131
-
125
-    err = kobject_init_and_add(wi_kobj, &wi_ktype, root_kobj,
132
-    err = kobject_init_and_add(wi_kobj, &wi_ktype, root_kobj,
126
+    err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj,
133
+    err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj,
127
                 "weighted_interleave");
134
                 "weighted_interleave");
128
-    if (err) {
135
    if (err)
129
-        kobject_put(wi_kobj);
136
        goto err_put_kobj;
130
+    if (err)
131
        goto err_out;
132
-    }
133
137
134
    for_each_node_state(nid, N_POSSIBLE) {
138
    for_each_node_state(nid, N_POSSIBLE) {
135
-        err = add_weight_node(nid, wi_kobj);
139
-        err = add_weight_node(nid, wi_kobj);
136
+        err = sysfs_wi_node_add(nid);
140
+        err = sysfs_wi_node_add(nid);
137
        if (err) {
141
        if (err) {
138
            pr_err("failed to add sysfs [node%d]\n", nid);
142
            pr_err("failed to add sysfs [node%d]\n", nid);
139
-            break;
143
            goto err_del_kobj;
140
+            goto err_out;
144
@@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *root_kobj)
141
        }
142
    }
143
-    if (err) {
144
-        kobject_put(wi_kobj);
145
-        goto err_out;
146
-    }
147
148
    return 0;
145
    return 0;
149
146
150
-node_out:
147
err_del_kobj:
151
-    kfree(node_attrs);
148
-    kobject_del(wi_kobj);
152
err_out:
149
+    kobject_del(&wi_group->wi_kobj);
150
err_put_kobj:
151
-    kobject_put(wi_kobj);
153
+    kobject_put(&wi_group->wi_kobj);
152
+    kobject_put(&wi_group->wi_kobj);
154
    return err;
153
    return err;
155
}
154
}
156
155
157
--
156
--
158
2.34.1
157
2.34.1
diff view generated by jsdifflib
...
...
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>
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
Reviewed-by: Oscar Salvador <osalvador@suse.de>
31
---
32
---
32
mm/mempolicy.c | 113 +++++++++++++++++++++++++++++++++++++++----------
33
mm/mempolicy.c | 106 ++++++++++++++++++++++++++++++++++++++-----------
33
1 file changed, 90 insertions(+), 23 deletions(-)
34
1 file changed, 83 insertions(+), 23 deletions(-)
34
35
35
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
36
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
36
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
37
--- a/mm/mempolicy.c
38
--- a/mm/mempolicy.c
38
+++ b/mm/mempolicy.c
39
+++ b/mm/mempolicy.c
...
...
52
    struct iw_node_attr *nattrs[];
53
    struct iw_node_attr *nattrs[];
53
};
54
};
54
55
55
@@ -XXX,XX +XXX,XX @@ static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr,
56
@@ -XXX,XX +XXX,XX @@ static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr,
56
57
57
static void sysfs_wi_node_release(int nid)
58
static void sysfs_wi_node_delete(int nid)
58
{
59
{
59
-    if (!wi_group->nattrs[nid])
60
-    if (!wi_group->nattrs[nid])
60
+    struct iw_node_attr *attr;
61
+    struct iw_node_attr *attr;
61
+
62
+
62
+    if (nid < 0 || nid >= nr_node_ids)
63
+    if (nid < 0 || nid >= nr_node_ids)
...
...
66
+    attr = wi_group->nattrs[nid];
67
+    attr = wi_group->nattrs[nid];
67
+    if (!attr) {
68
+    if (!attr) {
68
+        mutex_unlock(&wi_group->kobj_lock);
69
+        mutex_unlock(&wi_group->kobj_lock);
69
        return;
70
        return;
70
+    }
71
+    }
72
+
73
+    wi_group->nattrs[nid] = NULL;
74
+    mutex_unlock(&wi_group->kobj_lock);
71
75
72
-    sysfs_remove_file(&wi_group->wi_kobj,
76
-    sysfs_remove_file(&wi_group->wi_kobj,
73
-             &wi_group->nattrs[nid]->kobj_attr.attr);
77
-             &wi_group->nattrs[nid]->kobj_attr.attr);
74
-    kfree(wi_group->nattrs[nid]->kobj_attr.attr.name);
78
-    kfree(wi_group->nattrs[nid]->kobj_attr.attr.name);
75
-    kfree(wi_group->nattrs[nid]);
79
-    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);
80
+    sysfs_remove_file(&wi_group->wi_kobj, &attr->kobj_attr.attr);
80
+    kfree(attr->kobj_attr.attr.name);
81
+    kfree(attr->kobj_attr.attr.name);
81
+    kfree(attr);
82
+    kfree(attr);
82
}
83
}
83
84
...
...
121
+        pr_info("Node [%d] already exists\n", nid);
122
+        pr_info("Node [%d] already exists\n", nid);
122
+        kfree(new_attr);
123
+        kfree(new_attr);
123
+        kfree(name);
124
+        kfree(name);
124
+        return 0;
125
+        return 0;
125
+    }
126
+    }
127
+    wi_group->nattrs[nid] = new_attr;
126
128
127
-    if (sysfs_create_file(&wi_group->wi_kobj, &node_attr->kobj_attr.attr)) {
129
-    if (sysfs_create_file(&wi_group->wi_kobj, &node_attr->kobj_attr.attr)) {
128
-        kfree(node_attr->kobj_attr.attr.name);
130
-        kfree(node_attr->kobj_attr.attr.name);
129
-        kfree(node_attr);
131
-        kfree(node_attr);
130
-        pr_err("failed to add attribute to weighted_interleave\n");
132
-        pr_err("failed to add attribute to weighted_interleave\n");
131
-        return -ENOMEM;
133
-        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);
134
+    sysfs_attr_init(&wi_group->nattrs[nid]->kobj_attr.attr);
136
+    wi_group->nattrs[nid]->kobj_attr.attr.name = name;
135
+    wi_group->nattrs[nid]->kobj_attr.attr.name = name;
137
+    wi_group->nattrs[nid]->kobj_attr.attr.mode = 0644;
136
+    wi_group->nattrs[nid]->kobj_attr.attr.mode = 0644;
138
+    wi_group->nattrs[nid]->kobj_attr.show = node_show;
137
+    wi_group->nattrs[nid]->kobj_attr.show = node_show;
139
+    wi_group->nattrs[nid]->kobj_attr.store = node_store;
138
+    wi_group->nattrs[nid]->kobj_attr.store = node_store;
...
...
145
+        kfree(wi_group->nattrs[nid]->kobj_attr.attr.name);
144
+        kfree(wi_group->nattrs[nid]->kobj_attr.attr.name);
146
+        kfree(wi_group->nattrs[nid]);
145
+        kfree(wi_group->nattrs[nid]);
147
+        wi_group->nattrs[nid] = NULL;
146
+        wi_group->nattrs[nid] = NULL;
148
+        pr_err("Failed to add attribute to weighted_interleave: %d\n", ret);
147
+        pr_err("Failed to add attribute to weighted_interleave: %d\n", ret);
149
    }
148
    }
149
+    mutex_unlock(&wi_group->kobj_lock);
150
150
151
-    wi_group->nattrs[nid] = node_attr;
151
-    wi_group->nattrs[nid] = node_attr;
152
-    return 0;
152
-    return 0;
153
+    return ret;
153
+    return ret;
154
+}
154
+}
...
...
159
+    int err;
159
+    int err;
160
+    struct memory_notify *arg = data;
160
+    struct memory_notify *arg = data;
161
+    int nid = arg->status_change_nid;
161
+    int nid = arg->status_change_nid;
162
+
162
+
163
+    if (nid < 0)
163
+    if (nid < 0)
164
+        goto notifier_end;
164
+        return NOTIFY_OK;
165
+
165
+
166
+    switch(action) {
166
+    switch(action) {
167
+    case MEM_ONLINE:
167
+    case MEM_ONLINE:
168
+        if (node_state(nid, N_MEMORY)) {
168
+        err = sysfs_wi_node_add(nid);
169
+            err = sysfs_wi_node_add(nid);
169
+        if (err)
170
+            if (err) {
170
+            pr_err("failed to add sysfs [node%d]\n", nid);
171
+                pr_err("failed to add sysfs [node%d]\n", nid);
172
+                return NOTIFY_BAD;
173
+            }
174
+        }
175
+        break;
171
+        break;
176
+    case MEM_OFFLINE:
172
+    case MEM_OFFLINE:
177
+        if (!node_state(nid, N_MEMORY))
173
+        sysfs_wi_node_delete(nid);
178
+            sysfs_wi_node_release(nid);
179
+        break;
174
+        break;
180
+    }
175
+    }
181
+
176
+
182
+notifier_end:
183
+    return NOTIFY_OK;
177
+    return NOTIFY_OK;
184
}
178
}
185
179
186
static int add_weighted_interleave_group(struct kobject *mempolicy_kobj)
180
static int __init add_weighted_interleave_group(struct kobject *mempolicy_kobj)
187
@@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *mempolicy_kobj)
181
@@ -XXX,XX +XXX,XX @@ static int __init add_weighted_interleave_group(struct kobject *mempolicy_kobj)
188
         GFP_KERNEL);
182
             GFP_KERNEL);
189
    if (!wi_group)
183
    if (!wi_group)
190
        return -ENOMEM;
184
        return -ENOMEM;
191
+    mutex_init(&wi_group->kobj_lock);
185
+    mutex_init(&wi_group->kobj_lock);
192
186
193
    err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj,
187
    err = kobject_init_and_add(&wi_group->wi_kobj, &wi_ktype, mempolicy_kobj,
194
                 "weighted_interleave");
188
                 "weighted_interleave");
195
    if (err)
189
    if (err)
196
        goto err_out;
190
        goto err_put_kobj;
197
191
198
-    for_each_node_state(nid, N_POSSIBLE) {
192
-    for_each_node_state(nid, N_POSSIBLE) {
199
+    for_each_online_node(nid) {
193
+    for_each_online_node(nid) {
200
+        if (!node_state(nid, N_MEMORY))
194
+        if (!node_state(nid, N_MEMORY))
201
+            continue;
195
+            continue;
202
+
196
+
203
        err = sysfs_wi_node_add(nid);
197
        err = sysfs_wi_node_add(nid);
204
        if (err) {
198
        if (err) {
205
            pr_err("failed to add sysfs [node%d]\n", nid);
199
            pr_err("failed to add sysfs [node%d]\n", nid);
206
@@ -XXX,XX +XXX,XX @@ static int add_weighted_interleave_group(struct kobject *mempolicy_kobj)
200
@@ -XXX,XX +XXX,XX @@ static int __init add_weighted_interleave_group(struct kobject *mempolicy_kobj)
207
        }
201
        }
208
    }
202
    }
209
203
210
+    hotplug_memory_notifier(wi_node_notifier, DEFAULT_CALLBACK_PRI);
204
+    hotplug_memory_notifier(wi_node_notifier, DEFAULT_CALLBACK_PRI);
211
    return 0;
205
    return 0;
212
206
213
err_out:
207
err_del_kobj:
214
--
208
--
215
2.34.1
209
2.34.1
diff view generated by jsdifflib