Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.

Commit a0fcc4e

Browse files
committed
no_cpu_relax hack
Getting stashed dentry only for the bpf helper does not seem to work - the dentry is usually zero, so the fast path returns ENOENT. Going with slow path for the bpf helper is kind of icky, because the slow path can sleep. Since we don't want to sleep during the bpf helper function, allow going through the slow path without calling cpu_relax. All other callers of the function with the slow path are not affected. It kinda still stinks, because the bpf helper still has some busy loop… Signed-off-by: Krzesimir Nowak <[email protected]>
1 parent 1f1db24 commit a0fcc4e

File tree

1 file changed

+31
-14
lines changed

1 file changed

+31
-14
lines changed

fs/nsfs.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,13 @@ static struct dentry *__ns_get_stashed_dentry(struct ns_common *ns)
7070
return dentry;
7171
}
7272

73-
static void *__ns_get_path(struct path *path, struct ns_common *ns)
73+
enum ns_get_path_cpu_relax_mode {
74+
WITH_CPU_RELAX,
75+
NO_CPU_RELAX
76+
};
77+
78+
static void *__ns_get_path(struct path *path, struct ns_common *ns,
79+
enum ns_get_path_cpu_relax_mode cpu_relax_mode)
7480
{
7581
struct vfsmount *mnt = nsfs_mnt;
7682
struct dentry *dentry;
@@ -106,7 +112,8 @@ static void *__ns_get_path(struct path *path, struct ns_common *ns)
106112
if (d) {
107113
d_delete(dentry); /* make sure ->d_prune() does nothing */
108114
dput(dentry);
109-
cpu_relax();
115+
if (cpu_relax_mode == WITH_CPU_RELAX)
116+
cpu_relax();
110117
return ERR_PTR(-EAGAIN);
111118
}
112119
got_it:
@@ -115,9 +122,28 @@ static void *__ns_get_path(struct path *path, struct ns_common *ns)
115122
return NULL;
116123
}
117124

125+
static void *__ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb,
126+
void *private_data,
127+
enum ns_get_path_cpu_relax_mode cpu_relax_mode)
128+
{
129+
void *ret;
130+
131+
do {
132+
struct ns_common *ns = ns_get_cb(private_data);
133+
if (!ns)
134+
return ERR_PTR(-ENOENT);
135+
136+
ret = __ns_get_path(path, ns, cpu_relax_mode);
137+
} while (ret == ERR_PTR(-EAGAIN));
138+
139+
return ret;
140+
}
141+
118142
void *ns_get_path_cb_fast(struct path *path, ns_get_path_helper_t *ns_get_cb,
119143
void *private_data)
120144
{
145+
return __ns_get_path_cb(path, ns_get_cb, private_data, NO_CPU_RELAX);
146+
/*
121147
struct ns_common *ns = ns_get_cb(private_data);
122148
struct dentry *dentry;
123149
@@ -130,22 +156,13 @@ void *ns_get_path_cb_fast(struct path *path, ns_get_path_helper_t *ns_get_cb,
130156
path->mnt = mntget(nsfs_mnt);
131157
path->dentry = dentry;
132158
return NULL;
159+
*/
133160
}
134161

135162
void *ns_get_path_cb(struct path *path, ns_get_path_helper_t *ns_get_cb,
136163
void *private_data)
137164
{
138-
void *ret;
139-
140-
do {
141-
struct ns_common *ns = ns_get_cb(private_data);
142-
if (!ns)
143-
return ERR_PTR(-ENOENT);
144-
145-
ret = __ns_get_path(path, ns);
146-
} while (ret == ERR_PTR(-EAGAIN));
147-
148-
return ret;
165+
return __ns_get_path_cb(path, ns_get_cb, private_data, WITH_CPU_RELAX);
149166
}
150167

151168
struct ns_get_path_task_args {
@@ -192,7 +209,7 @@ int open_related_ns(struct ns_common *ns,
192209
return PTR_ERR(relative);
193210
}
194211

195-
err = __ns_get_path(&path, relative);
212+
err = __ns_get_path(&path, relative, WITH_CPU_RELAX);
196213
} while (err == ERR_PTR(-EAGAIN));
197214

198215
if (IS_ERR(err)) {

0 commit comments

Comments
 (0)