* [PATCH 1/2] module: expose imported namespaces via sysfs
@ 2026-01-08 4:47 Nicholas Sielicki
2026-01-08 4:47 ` [PATCH 2/2] docs: symbol-namespaces: mention sysfs attribute Nicholas Sielicki
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Nicholas Sielicki @ 2026-01-08 4:47 UTC (permalink / raw)
To: Luis Chamberlain, Petr Pavlu, Daniel Gomez
Cc: Sami Tolvanen, Aaron Tomlin, Matthias Maennich, Peter Zijlstra,
Jonathan Corbet, Randy Dunlap, linux-modules, linux-kernel,
Nicholas Sielicki
Currently, the only way for userspace to determine which symbol
namespaces a module imports is to locate the .ko file on disk (which may
not match the loaded module), then either parsing the binary manually
and handling any potential compression, or shelling-out to modinfo.
This is painful in cases where userspace wants to distinguish between
module variants that share the same name but import different
namespaces. For example, the nvidia-uvm module exists in both open and
closed source variants; the open source version imports the DMA_BUF
namespace while the closed source version does not, and networking
middleware may want to initialize itself differently depending on that.
Add /sys/module/*/import_ns to expose imported namespaces for loaded
modules. The file contains one namespace per line and only exists for
modules that import at least one namespace.
Signed-off-by: Nicholas Sielicki <linux@opensource.nslick.com>
---
Documentation/ABI/testing/sysfs-module | 9 ++++
include/linux/module.h | 1 +
kernel/module/main.c | 62 +++++++++++++++++++++++++-
3 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-module b/Documentation/ABI/testing/sysfs-module
index 6bc9af6229f0..d8e2a33fd514 100644
--- a/Documentation/ABI/testing/sysfs-module
+++ b/Documentation/ABI/testing/sysfs-module
@@ -48,6 +48,15 @@ Contact: Kay Sievers <kay.sievers@vrfy.org>
Description: Show the initialization state(live, coming, going) of
the module.
+What: /sys/module/*/import_ns
+Date: January 2026
+KernelVersion: 6.20
+Contact: linux-modules@vger.kernel.org
+Description: List of symbol namespaces imported by this module via
+ MODULE_IMPORT_NS(). Each namespace appears on a separate line.
+ This file only exists for modules that import at least one
+ namespace.
+
What: /sys/module/*/taint
Date: Jan 2012
KernelVersion: 3.3
diff --git a/include/linux/module.h b/include/linux/module.h
index d80c3ea57472..f1bcca03f90b 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -419,6 +419,7 @@ struct module {
struct module_attribute *modinfo_attrs;
const char *version;
const char *srcversion;
+ const char *imported_namespaces;
struct kobject *holders_dir;
/* Exported symbols */
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 710ee30b3bea..6c41934f1135 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -607,6 +607,23 @@ static const struct module_attribute modinfo_##field = { \
MODINFO_ATTR(version);
MODINFO_ATTR(srcversion);
+static ssize_t show_modinfo_import_ns(const struct module_attribute *mattr,
+ struct module_kobject *mk, char *buffer)
+{
+ return sysfs_emit(buffer, "%s\n", mk->mod->imported_namespaces);
+}
+
+static int modinfo_import_ns_exists(struct module *mod)
+{
+ return mod->imported_namespaces != NULL;
+}
+
+static const struct module_attribute modinfo_import_ns = {
+ .attr = { .name = "import_ns", .mode = 0444 },
+ .show = show_modinfo_import_ns,
+ .test = modinfo_import_ns_exists,
+};
+
static struct {
char name[MODULE_NAME_LEN];
char taints[MODULE_FLAGS_BUF_SIZE];
@@ -1058,6 +1075,7 @@ const struct module_attribute *const modinfo_attrs[] = {
&module_uevent,
&modinfo_version,
&modinfo_srcversion,
+ &modinfo_import_ns,
&modinfo_initstate,
&modinfo_coresize,
#ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC
@@ -1753,11 +1771,48 @@ static void module_license_taint_check(struct module *mod, const char *license)
}
}
+static int copy_modinfo_import_ns(struct module *mod, struct load_info *info)
+{
+ char *ns;
+ size_t len, total_len = 0;
+ char *buf, *p;
+
+ for_each_modinfo_entry(ns, info, "import_ns")
+ total_len += strlen(ns) + 1;
+
+ if (!total_len) {
+ mod->imported_namespaces = NULL;
+ return 0;
+ }
+
+ buf = kmalloc(total_len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ p = buf;
+ for_each_modinfo_entry(ns, info, "import_ns") {
+ len = strlen(ns);
+ memcpy(p, ns, len);
+ p += len;
+ *p++ = '\n';
+ }
+ /* Replace trailing newline with null terminator. */
+ *(p - 1) = '\0';
+
+ mod->imported_namespaces = buf;
+ return 0;
+}
+
+static void free_modinfo_import_ns(struct module *mod)
+{
+ kfree(mod->imported_namespaces);
+}
+
static int setup_modinfo(struct module *mod, struct load_info *info)
{
const struct module_attribute *attr;
char *imported_namespace;
- int i;
+ int i, err;
for (i = 0; (attr = modinfo_attrs[i]); i++) {
if (attr->setup)
@@ -1776,6 +1831,10 @@ static int setup_modinfo(struct module *mod, struct load_info *info)
}
}
+ err = copy_modinfo_import_ns(mod, info);
+ if (err)
+ return err;
+
return 0;
}
@@ -1788,6 +1847,7 @@ static void free_modinfo(struct module *mod)
if (attr->free)
attr->free(mod);
}
+ free_modinfo_import_ns(mod);
}
bool __weak module_init_section(const char *name)
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] docs: symbol-namespaces: mention sysfs attribute
2026-01-08 4:47 [PATCH 1/2] module: expose imported namespaces via sysfs Nicholas Sielicki
@ 2026-01-08 4:47 ` Nicholas Sielicki
2026-02-13 17:44 ` [PATCH 1/2] module: expose imported namespaces via sysfs Sami Tolvanen
2026-03-05 22:32 ` Sami Tolvanen
2 siblings, 0 replies; 5+ messages in thread
From: Nicholas Sielicki @ 2026-01-08 4:47 UTC (permalink / raw)
To: Luis Chamberlain, Petr Pavlu, Daniel Gomez
Cc: Sami Tolvanen, Aaron Tomlin, Matthias Maennich, Peter Zijlstra,
Jonathan Corbet, Randy Dunlap, linux-modules, linux-kernel,
Nicholas Sielicki
Reference the new /sys/module/*/import_ns sysfs attribute in docs as an
alternative to modinfo for inspecting imported namespaces of loaded
modules.
Signed-off-by: Nicholas Sielicki <linux@opensource.nslick.com>
---
Documentation/core-api/symbol-namespaces.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/core-api/symbol-namespaces.rst b/Documentation/core-api/symbol-namespaces.rst
index 034898e81ba2..2304d5bffcce 100644
--- a/Documentation/core-api/symbol-namespaces.rst
+++ b/Documentation/core-api/symbol-namespaces.rst
@@ -114,6 +114,11 @@ inspected with modinfo::
import_ns: USB_STORAGE
[...]
+For modules that are currently loaded, imported namespaces are also available
+via sysfs::
+
+ $ cat /sys/module/ums_karma/import_ns
+ USB_STORAGE
It is advisable to add the MODULE_IMPORT_NS() statement close to other module
metadata definitions like MODULE_AUTHOR() or MODULE_LICENSE().
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] module: expose imported namespaces via sysfs
2026-01-08 4:47 [PATCH 1/2] module: expose imported namespaces via sysfs Nicholas Sielicki
2026-01-08 4:47 ` [PATCH 2/2] docs: symbol-namespaces: mention sysfs attribute Nicholas Sielicki
@ 2026-02-13 17:44 ` Sami Tolvanen
2026-02-13 20:25 ` Nicholas Sielicki
2026-03-05 22:32 ` Sami Tolvanen
2 siblings, 1 reply; 5+ messages in thread
From: Sami Tolvanen @ 2026-02-13 17:44 UTC (permalink / raw)
To: linux
Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Aaron Tomlin,
Matthias Maennich, Peter Zijlstra, Jonathan Corbet, Randy Dunlap,
linux-modules, linux-kernel
Hi Nicholas,
On Wed, Jan 7, 2026 at 8:47 PM Nicholas Sielicki
<linux@opensource.nslick.com> wrote:
>
> Currently, the only way for userspace to determine which symbol
> namespaces a module imports is to locate the .ko file on disk (which may
> not match the loaded module), then either parsing the binary manually
> and handling any potential compression, or shelling-out to modinfo.
>
> This is painful in cases where userspace wants to distinguish between
> module variants that share the same name but import different
> namespaces. For example, the nvidia-uvm module exists in both open and
> closed source variants; the open source version imports the DMA_BUF
> namespace while the closed source version does not, and networking
> middleware may want to initialize itself differently depending on that.
>
> Add /sys/module/*/import_ns to expose imported namespaces for loaded
> modules. The file contains one namespace per line and only exists for
> modules that import at least one namespace.
The patches look reasonable to me, but I do wonder if examining
imported namespaces is the best way to distinguish between module
variants. Is looking at /sys/module/*/taint not sufficient for your
use case?
Sami
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] module: expose imported namespaces via sysfs
2026-02-13 17:44 ` [PATCH 1/2] module: expose imported namespaces via sysfs Sami Tolvanen
@ 2026-02-13 20:25 ` Nicholas Sielicki
0 siblings, 0 replies; 5+ messages in thread
From: Nicholas Sielicki @ 2026-02-13 20:25 UTC (permalink / raw)
To: Sami Tolvanen
Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Aaron Tomlin,
Matthias Maennich, Peter Zijlstra, Jonathan Corbet, Randy Dunlap,
linux-modules, linux-kernel
On Fri, Feb 13, 2026, at 11:44, Sami Tolvanen wrote:
> The patches look reasonable to me, but I do wonder if examining
> imported namespaces is the best way to distinguish between module
> variants. Is looking at /sys/module/*/taint not sufficient for your
> use case?
You're right that the example in the commit message is bad; it's true that the
taint bit is strictly mutually exclusive with dmabuf support, at least for the
way that this evolved in the nvidia open module. This is a patch I had in the
back of my head for a while, and the details had become murkier since.
The actual problem I wanted to solve with this was not with dmabuf being
conditionally available on the exporter side (where the taint bit, albeit
imprecise, would have worked), but with determining whether the ioctl was
present on the import side, which was only true from 5.12 onward for uverbs
(commit bfe0cc6).
So on eg: a system with untainted nvidia-open on 5.10, it was viable to export
dmabufs from device memory, but ibv_reg_dmabuf_mr would fail at runtime because
the ioctl didn't exist yet. The workaround for my specific piece of middleware
was just to call uname and check for 5.12+ before advertising dmabuf support
back to the caller, but this left me feeling gross.
In reality, this patch doesn't solve that problem, because any system running a
new enough kernel to have this patch will already have support on both
import/export sides. But it's what made me wish this functionality existed.
Why I still hope you'll take this patch:
1. cheaply exposing module namespace imports under sysfs can be useful beyond
this specific situation. The kernel is already tracking this and validating it
for other reasons, so it's easy to also just expose it.
2. taint may not always be mutually exclusive with a module namespace import,
eg: in the case of uverbs above.
3. currently, the only way to determine whether a module speaks dmabuf at
runtime is to hardcode module-specific priors around the kernel version and/or
the taint bit, or to link proprietary vendor libraries and check for things
like CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED. Exposing this under sysfs provides
a cheaper way for networking middleware (that doesn't usually allocate device
memory itself and largely wishes to just blindly plumb dmabufs fds from callers
into some importer in a vendor agnostic way) to determine what modules are
in-play during initialization:
> user@host$ grep DMA_BUF /sys/module/*/import_ns
> /sys/module/amdgpu/import_ns:DMA_BUF
> /sys/module/ib_uverbs/import_ns:DMA_BUF
Critically, it can do this check without needing to link any vendor libraries.
As an example, libfabric currently contains an enum for heterogeneous memory
types, spanning ZE/ROCM/CUDA/SYNAPSEAI/NEURON... but libfabric doesn't need to
allocate device memory itself (it is provided by the caller, hopefully as a
dmabuf), and regardless of what module exported it, all roads will eventually
lead back to a generic dmabuf fd import ioctl for the NIC.
Despite that, to prevent memory registration errors at runtime before they
happen, it needs to probe support for these memory types at initialization
time. Today, that essentially means needing to link a new proprietary vendor
library to query dmabuf export support using a vendor-specific API. But without
any existing mechanism in the kernel to query known dmabuf importers or
exporters, even a suboptimal one, this is what is done in practice.
Best,
Nicholas
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] module: expose imported namespaces via sysfs
2026-01-08 4:47 [PATCH 1/2] module: expose imported namespaces via sysfs Nicholas Sielicki
2026-01-08 4:47 ` [PATCH 2/2] docs: symbol-namespaces: mention sysfs attribute Nicholas Sielicki
2026-02-13 17:44 ` [PATCH 1/2] module: expose imported namespaces via sysfs Sami Tolvanen
@ 2026-03-05 22:32 ` Sami Tolvanen
2 siblings, 0 replies; 5+ messages in thread
From: Sami Tolvanen @ 2026-03-05 22:32 UTC (permalink / raw)
To: Nicholas Sielicki
Cc: Luis Chamberlain, Petr Pavlu, Daniel Gomez, Aaron Tomlin,
Matthias Maennich, Peter Zijlstra, Jonathan Corbet, Randy Dunlap,
linux-modules, linux-kernel
On Wed, Jan 07, 2026 at 10:47:09PM -0600, Nicholas Sielicki wrote:
>
> +static ssize_t show_modinfo_import_ns(const struct module_attribute *mattr,
> + struct module_kobject *mk, char *buffer)
> +{
> + return sysfs_emit(buffer, "%s\n", mk->mod->imported_namespaces);
> +}
> +
> +static int modinfo_import_ns_exists(struct module *mod)
> +{
> + return mod->imported_namespaces != NULL;
> +}
> +
> +static const struct module_attribute modinfo_import_ns = {
> + .attr = { .name = "import_ns", .mode = 0444 },
> + .show = show_modinfo_import_ns,
> + .test = modinfo_import_ns_exists,
> +};
> +
Don't we need a .setup function that initializes mod->imported_namespaces
to NULL? Currently, if setup_modinfo returns an error, the pointer remains
initialized to whatever value we read from .gnu.linkonce.this_module, and
we'll pass that arbitrary pointer to kfree.
This isn't normally a problem since modpost zero-initializes the field, but
we don't want to rely on userspace to initialize our pointers.
Also, define .free to release the buffer instead of adding a direct call
to free_modinfo.
> static struct {
> char name[MODULE_NAME_LEN];
> char taints[MODULE_FLAGS_BUF_SIZE];
> @@ -1058,6 +1075,7 @@ const struct module_attribute *const modinfo_attrs[] = {
> &module_uevent,
> &modinfo_version,
> &modinfo_srcversion,
> + &modinfo_import_ns,
> &modinfo_initstate,
> &modinfo_coresize,
> #ifdef CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC
> @@ -1753,11 +1771,48 @@ static void module_license_taint_check(struct module *mod, const char *license)
> }
> }
>
> +static int copy_modinfo_import_ns(struct module *mod, struct load_info *info)
> +{
> + char *ns;
> + size_t len, total_len = 0;
> + char *buf, *p;
> +
> + for_each_modinfo_entry(ns, info, "import_ns")
> + total_len += strlen(ns) + 1;
> +
> + if (!total_len) {
> + mod->imported_namespaces = NULL;
> + return 0;
> + }
> +
> + buf = kmalloc(total_len, GFP_KERNEL);
> + if (!buf)
> + return -ENOMEM;
For example, if kmalloc fails, mod->imported_namespaces isn't initialized.
> +
> + p = buf;
> + for_each_modinfo_entry(ns, info, "import_ns") {
> + len = strlen(ns);
> + memcpy(p, ns, len);
> + p += len;
> + *p++ = '\n';
> + }
> + /* Replace trailing newline with null terminator. */
> + *(p - 1) = '\0';
> +
> + mod->imported_namespaces = buf;
> + return 0;
> +}
> +
> +static void free_modinfo_import_ns(struct module *mod)
> +{
> + kfree(mod->imported_namespaces);
mod->imported_namespaces = NULL;
> +}
> +
> static int setup_modinfo(struct module *mod, struct load_info *info)
> {
> const struct module_attribute *attr;
> char *imported_namespace;
> - int i;
> + int i, err;
>
> for (i = 0; (attr = modinfo_attrs[i]); i++) {
> if (attr->setup)
> @@ -1776,6 +1831,10 @@ static int setup_modinfo(struct module *mod, struct load_info *info)
> }
> }
Also setup_modinfo can fail before copy_modinfo_import_ns is even
called.
> + err = copy_modinfo_import_ns(mod, info);
> + if (err)
> + return err;
> +
Sami
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-03-05 22:32 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-08 4:47 [PATCH 1/2] module: expose imported namespaces via sysfs Nicholas Sielicki
2026-01-08 4:47 ` [PATCH 2/2] docs: symbol-namespaces: mention sysfs attribute Nicholas Sielicki
2026-02-13 17:44 ` [PATCH 1/2] module: expose imported namespaces via sysfs Sami Tolvanen
2026-02-13 20:25 ` Nicholas Sielicki
2026-03-05 22:32 ` Sami Tolvanen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox