linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] kernel/module: add documentation for try_module_get()
@ 2023-03-10 19:04 Luis Chamberlain
  0 siblings, 0 replies; 12+ messages in thread
From: Luis Chamberlain @ 2023-03-10 19:04 UTC (permalink / raw)
  To: linux-modules, linux-kernel, tj, bpf
  Cc: christophe.leroy, jolsa, vmalik, john.fastabend, andrii,
	martin.lau, song, yhs, kpsingh, sdf, haoluo, nick.alcock,
	keescook, gregkh, tglx, mcgrof

There is quite a bit of tribal knowledge around proper use of try_module_get()
and requiring *somehow* the module to still exist to use this call in a way
that is safe. Document this bit of tribal knowledge. To be clear, you should
only use try_module_get() *iff* you are 100% sure the module already does
exist and is not on its way out.

You can be sure the module still exists and is alive through:

1) Direct protection with its refcount: you know some earlier caller called
   __module_get() safely
2) Implied protection: there is an implied protection against module removal

Having an idea of when you are sure __module_get() might be called earlier is
easy to understand however the implied protection requires an example. We use
sysfs an an example for implied protection without a direct module reference
count bump. kernfs / sysfs uses its own internal reference counting for files
being actively used, when such file are active they completely prevent
the module from being removed. kernfs protects this with its kernfs_active().
Effort has been put into verifying the kernfs implied protection works by
using a currently out-of-tree test_sysfs selftest test #32 [0]:

./tools/testing/selftests/sysfs/sysfs.sh -t 0032

Without kernfs / sysfs preventing module removal through its active reference
count (kernfs_active()) the write would fail or worse, a crash would happen in
this test and it does not.

Similar safeguards are required for other users of try_module_get() *iff*
they are not ensuring the above rule 1) is followed.

[0] https://lore.kernel.org/lkml/20211029184500.2821444-4-mcgrof@kernel.org/

Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
---

I had actually written an initial version of these docs [0] *two years* ago
through my test_sysfs patches [1]. Back then the only pushback I got to get this
test upstream was Greg's opposition to me using copyleft-next for my test driver.
Upon feedback from the comunity, we've now have passed that hurtle, and we
have proper SPDX tags for copyleft-next driver upstream. Before I follow up
again with that test_sysfs driver though *this* patch in particular seems
important enough to get upstream and so sending this separately because
I see some folks might still be in high need of these docs.

I'll reply to the thread / patch in question next.

[0] https://lore.kernel.org/all/20211029184500.2821444-7-mcgrof@kernel.org/
[1] https://lore.kernel.org/all/20211029184500.2821444-1-mcgrof@kernel.org/

 include/linux/module.h | 40 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 2 deletions(-)

diff --git a/include/linux/module.h b/include/linux/module.h
index 91726444d55f..c3b357196470 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -671,10 +671,46 @@ void symbol_put_addr(void *addr);
    to handle the error case (which only happens with rmmod --wait). */
 extern void __module_get(struct module *module);
 
-/* This is the Right Way to get a module: if it fails, it's being removed,
- * so pretend it's not there. */
+/**
+ * try_module_get() - take module refcount unless module is being removed
+ * @module: the module we should check for
+ *
+ * Only try to get a module reference count if the module is not being removed.
+ * This call will fail if the module is already being removed.
+ *
+ * Care must also be taken to ensure the module exists and is alive prior to
+ * usage of this call. This can be gauranteed through two means:
+ *
+ * 1) Direct protection: you know an earlier caller must have increased the
+ *    module reference through __module_get(). This can typically be achieved
+ *    by having another entity other than the module itself increment the
+ *    module reference count.
+ *
+ * 2) Implied protection: there is an implied protection against module
+ *    removal. An example of this is the implied protection used by kernfs /
+ *    sysfs. The sysfs store / read file operations are guaranteed to exist
+ *    through the use of kernfs's active reference (see kernfs_active()) and a
+ *    sysfs / kernfs file removal cannot happen unless the same file is not
+ *    active. Therefore, if a sysfs file is being read or written to the module
+ *    which created it must still exist. It is therefore safe to use
+ *    try_module_get() on module sysfs store / read ops.
+ *
+ * One of the real values to try_module_get() is the module_is_live() check
+ * which ensures that the caller of try_module_get() can yield to userspace
+ * module removal requests and gracefully fail if the module is on its way out.
+ *
+ * Returns true if the reference count was successfully incremented.
+ */
 extern bool try_module_get(struct module *module);
 
+/**
+ * module_put() - release a reference count to a module
+ * @module: the module we should release a reference count for
+ *
+ * If you successfully bump a reference count to a module with try_module_get(),
+ * when you are finished you must call module_put() to release that reference
+ * count.
+ */
 extern void module_put(struct module *module);
 
 #else /*!CONFIG_MODULE_UNLOAD*/
-- 
2.39.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread
* [PATCH] kernel/module: add documentation for try_module_get()
@ 2021-07-22 22:19 Luis Chamberlain
  2021-07-22 22:39 ` Stephen Hemminger
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Luis Chamberlain @ 2021-07-22 22:19 UTC (permalink / raw)
  To: gregkh, tj, shuah, akpm, rafael, davem, kuba, ast, andriin,
	daniel, atenart, alobakin, weiwan, ap420073
  Cc: jeyu, ngupta, sergey.senozhatsky.work, minchan, mcgrof, axboe,
	mbenes, jpoimboe, tglx, keescook, jikos, rostedt, peterz,
	linux-block, netdev, linux-kselftest, linux-kernel

There is quite a bit of tribal knowledge around proper use of
try_module_get() and that it must be used only in a context which
can ensure the module won't be gone during the operation. Document
this little bit of tribal knowledge.

Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
---
 kernel/module.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/kernel/module.c b/kernel/module.c
index ed13917ea5f3..0d609647a54d 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1066,6 +1066,28 @@ void __module_get(struct module *module)
 }
 EXPORT_SYMBOL(__module_get);
 
+/**
+ * try_module_get - yields to module removal and bumps reference count otherwise
+ * @module: the module we should check for
+ *
+ * This can be used to check if userspace has requested to remove a module,
+ * and if so let the caller give up. Otherwise it takes a reference count to
+ * ensure a request from userspace to remove the module cannot happen.
+ *
+ * Care must be taken to ensure the module cannot be removed during
+ * try_module_get(). This can be done by having another entity other than the
+ * module itself increment the module reference count, or through some other
+ * means which gaurantees the module could not be removed during an operation.
+ * An example of this later case is using this call in a sysfs file which the
+ * module created. The sysfs store / read file operation is ensured to exist
+ * and still be present by kernfs's active reference. If a sysfs file operation
+ * is being run, the module which created it must still exist as the module is
+ * in charge of removal of the sysfs file.
+ *
+ * The real value to try_module_get() is the module_is_live() check which
+ * ensures this the caller of try_module_get() can yields to userspace module
+ * removal requests and fail whatever it was about to process.
+ */
 bool try_module_get(struct module *module)
 {
 	bool ret = true;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-03-10 19:05 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-03-10 19:04 [PATCH] kernel/module: add documentation for try_module_get() Luis Chamberlain
  -- strict thread matches above, loose matches on Subject: below --
2021-07-22 22:19 Luis Chamberlain
2021-07-22 22:39 ` Stephen Hemminger
2021-07-23  2:33 ` Bart Van Assche
2021-07-24 12:15 ` David Laight
2021-07-27 17:30   ` Luis Chamberlain
2021-07-27 17:46     ` gregkh
2021-07-27 18:18       ` Luis Chamberlain
2021-07-27 18:38         ` gregkh
2021-07-27 20:54           ` Luis Chamberlain
2021-07-28  8:28             ` David Laight
2021-07-28 13:49               ` Luis Chamberlain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).