<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/kernel/module.c, branch v3.19-rc2</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://www.git.shady.money/linux/atom?h=v3.19-rc2</id>
<link rel='self' href='https://www.git.shady.money/linux/atom?h=v3.19-rc2'/>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/'/>
<updated>2014-12-19T04:55:41Z</updated>
<entry>
<title>Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux</title>
<updated>2014-12-19T04:55:41Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2014-12-19T04:55:41Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=d790be3863b28fd22e0781c1a3ddefcbfd5f7086'/>
<id>urn:sha1:d790be3863b28fd22e0781c1a3ddefcbfd5f7086</id>
<content type='text'>
Pull module updates from Rusty Russell:
 "The exciting thing here is the getting rid of stop_machine on module
  removal.  This is possible by using a simple atomic_t for the counter,
  rather than our fancy per-cpu counter: it turns out that no one is
  doing a module increment per net packet, so the slowdown should be in
  the noise"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  param: do not set store func without write perm
  params: cleanup sysfs allocation
  kernel:module Fix coding style errors and warnings.
  module: Remove stop_machine from module unloading
  module: Replace module_ref with atomic_t refcnt
  lib/bug: Use RCU list ops for module_bug_list
  module: Unlink module with RCU synchronizing instead of stop_machine
  module: Wait for RCU synchronizing before releasing a module
</content>
</entry>
<entry>
<title>kernel:module Fix coding style errors and warnings.</title>
<updated>2014-11-11T06:37:47Z</updated>
<author>
<name>Ionut Alexa</name>
<email>ionut.m.alexa@gmail.com</email>
</author>
<published>2014-11-09T23:01:29Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=6da0b565150b32318757062bc75834113f0508d6'/>
<id>urn:sha1:6da0b565150b32318757062bc75834113f0508d6</id>
<content type='text'>
Fixed codin style errors and warnings. Changes printk with
print_debug/warn. Changed seq_printf to seq_puts.

Signed-off-by: Ionut Alexa &lt;ionut.m.alexa@gmail.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt; (removed bogus KERN_DEFAULT conversion)
</content>
</entry>
<entry>
<title>module: Remove stop_machine from module unloading</title>
<updated>2014-11-11T06:37:46Z</updated>
<author>
<name>Masami Hiramatsu</name>
<email>masami.hiramatsu.pt@hitachi.com</email>
</author>
<published>2014-11-09T23:00:29Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=e513cc1c07e2ab93a4514eec9833e031df3e30bb'/>
<id>urn:sha1:e513cc1c07e2ab93a4514eec9833e031df3e30bb</id>
<content type='text'>
Remove stop_machine from module unloading by adding new reference
counting algorithm.

This atomic refcounter works like a semaphore, it can get (be
incremented) only when the counter is not 0. When loading a module,
kmodule subsystem sets the counter MODULE_REF_BASE (= 1). And when
unloading the module, it subtracts MODULE_REF_BASE from the counter.
If no one refers the module, the refcounter becomes 0 and we can
remove the module safely. If someone referes it, we try to recover
the counter by adding MODULE_REF_BASE unless the counter becomes 0,
because the referrer can put the module right before recovering.
If the recovering is failed, we can get the 0 refcount and it
never be incremented again, it can be removed safely too.

Note that __module_get() forcibly gets the module refcounter,
users should use try_module_get() instead of that.

Signed-off-by: Masami Hiramatsu &lt;masami.hiramatsu.pt@hitachi.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
</content>
</entry>
<entry>
<title>module: Replace module_ref with atomic_t refcnt</title>
<updated>2014-11-11T06:37:46Z</updated>
<author>
<name>Masami Hiramatsu</name>
<email>masami.hiramatsu.pt@hitachi.com</email>
</author>
<published>2014-11-09T22:59:29Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=2f35c41f58a978dfa44ffa102249d556caa99eeb'/>
<id>urn:sha1:2f35c41f58a978dfa44ffa102249d556caa99eeb</id>
<content type='text'>
Replace module_ref per-cpu complex reference counter with
an atomic_t simple refcnt. This is for code simplification.

Signed-off-by: Masami Hiramatsu &lt;masami.hiramatsu.pt@hitachi.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
</content>
</entry>
<entry>
<title>lib/bug: Use RCU list ops for module_bug_list</title>
<updated>2014-11-11T06:37:46Z</updated>
<author>
<name>Masami Hiramatsu</name>
<email>masami.hiramatsu.pt@hitachi.com</email>
</author>
<published>2014-11-09T22:58:29Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=0286b5ea125e58b4797747f688949c05394412e8'/>
<id>urn:sha1:0286b5ea125e58b4797747f688949c05394412e8</id>
<content type='text'>
Actually since module_bug_list should be used in BUG context,
we may not need this. But for someone who want to use this
from normal context, this makes module_bug_list an RCU list.

Signed-off-by: Masami Hiramatsu &lt;masami.hiramatsu.pt@hitachi.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
</content>
</entry>
<entry>
<title>module: Unlink module with RCU synchronizing instead of stop_machine</title>
<updated>2014-11-11T06:37:45Z</updated>
<author>
<name>Masami Hiramatsu</name>
<email>masami.hiramatsu.pt@hitachi.com</email>
</author>
<published>2014-11-09T22:57:29Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=461e34aed0550fee706a9a28fb453830b5079ea0'/>
<id>urn:sha1:461e34aed0550fee706a9a28fb453830b5079ea0</id>
<content type='text'>
Unlink module from module list with RCU synchronizing instead
of using stop_machine(). Since module list is already protected
by rcu, we don't need stop_machine() anymore.

Signed-off-by: Masami Hiramatsu &lt;masami.hiramatsu.pt@hitachi.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
</content>
</entry>
<entry>
<title>module: Wait for RCU synchronizing before releasing a module</title>
<updated>2014-11-11T06:37:44Z</updated>
<author>
<name>Masami Hiramatsu</name>
<email>masami.hiramatsu.pt@hitachi.com</email>
</author>
<published>2014-11-09T22:56:29Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=4f48795b6154852d07d971e402c35ecc460ddcb6'/>
<id>urn:sha1:4f48795b6154852d07d971e402c35ecc460ddcb6</id>
<content type='text'>
Wait for RCU synchronizing on failure path of module loading
before releasing struct module, because the memory of mod-&gt;list
can still be accessed by list walkers (e.g. kallsyms).

Signed-off-by: Masami Hiramatsu &lt;masami.hiramatsu.pt@hitachi.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
</content>
</entry>
<entry>
<title>sched, modules: Fix nested sleep in add_unformed_module()</title>
<updated>2014-10-28T09:56:30Z</updated>
<author>
<name>Peter Zijlstra</name>
<email>peterz@infradead.org</email>
</author>
<published>2014-09-24T08:18:53Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=3c9b2c3d64a49f264422d7743599cf7f6535972d'/>
<id>urn:sha1:3c9b2c3d64a49f264422d7743599cf7f6535972d</id>
<content type='text'>
This is a genuine bug in add_unformed_module(), we cannot use blocking
primitives inside a wait loop.

So rewrite the wait_event_interruptible() usage to use the fresh
wait_woken() stuff.

Reported-by: Fengguang Wu &lt;fengguang.wu@intel.com&gt;
Signed-off-by: Peter Zijlstra (Intel) &lt;peterz@infradead.org&gt;
Cc: tglx@linutronix.de
Cc: ilya.dryomov@inktank.com
Cc: umgwanakikbuti@gmail.com
Cc: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Cc: oleg@redhat.com
Cc: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Cc: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Cc: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
Link: http://lkml.kernel.org/r/20140924082242.458562904@infradead.org
[ So this is probably complex to backport and the race wasn't reported AFAIK,
  so not marked for -stable. ]
Signed-off-by: Ingo Molnar &lt;mingo@kernel.org&gt;

Signed-off-by: Ingo Molnar &lt;mingo@kernel.org&gt;
</content>
</entry>
<entry>
<title>Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux</title>
<updated>2014-10-18T17:24:26Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2014-10-18T17:24:26Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=50edb5cc22c7b2ea7df095913596e5a649bd6b41'/>
<id>urn:sha1:50edb5cc22c7b2ea7df095913596e5a649bd6b41</id>
<content type='text'>
Pull module fix from Rusty Russell:
 "A single panic fix for a rare race, stable CC'd"

* tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  modules, lock around setting of MODULE_STATE_UNFORMED
</content>
</entry>
<entry>
<title>modules, lock around setting of MODULE_STATE_UNFORMED</title>
<updated>2014-10-14T23:50:09Z</updated>
<author>
<name>Prarit Bhargava</name>
<email>prarit@redhat.com</email>
</author>
<published>2014-10-13T16:21:39Z</published>
<link rel='alternate' type='text/html' href='https://www.git.shady.money/linux/commit/?id=d3051b489aa81ca9ba62af366149ef42b8dae97c'/>
<id>urn:sha1:d3051b489aa81ca9ba62af366149ef42b8dae97c</id>
<content type='text'>
A panic was seen in the following sitation.

There are two threads running on the system. The first thread is a system
monitoring thread that is reading /proc/modules. The second thread is
loading and unloading a module (in this example I'm using my simple
dummy-module.ko).  Note, in the "real world" this occurred with the qlogic
driver module.

When doing this, the following panic occurred:

 ------------[ cut here ]------------
 kernel BUG at kernel/module.c:3739!
 invalid opcode: 0000 [#1] SMP
 Modules linked in: binfmt_misc sg nfsv3 rpcsec_gss_krb5 nfsv4 dns_resolver nfs fscache intel_powerclamp coretemp kvm_intel kvm crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel aesni_intel lrw igb gf128mul glue_helper iTCO_wdt iTCO_vendor_support ablk_helper ptp sb_edac cryptd pps_core edac_core shpchp i2c_i801 pcspkr wmi lpc_ich ioatdma mfd_core dca ipmi_si nfsd ipmi_msghandler auth_rpcgss nfs_acl lockd sunrpc xfs libcrc32c sr_mod cdrom sd_mod crc_t10dif crct10dif_common mgag200 syscopyarea sysfillrect sysimgblt i2c_algo_bit drm_kms_helper ttm isci drm libsas ahci libahci scsi_transport_sas libata i2c_core dm_mirror dm_region_hash dm_log dm_mod [last unloaded: dummy_module]
 CPU: 37 PID: 186343 Comm: cat Tainted: GF          O--------------   3.10.0+ #7
 Hardware name: Intel Corporation S2600CP/S2600CP, BIOS RMLSDP.86I.00.29.D696.1311111329 11/11/2013
 task: ffff8807fd2d8000 ti: ffff88080fa7c000 task.ti: ffff88080fa7c000
 RIP: 0010:[&lt;ffffffff810d64c5&gt;]  [&lt;ffffffff810d64c5&gt;] module_flags+0xb5/0xc0
 RSP: 0018:ffff88080fa7fe18  EFLAGS: 00010246
 RAX: 0000000000000003 RBX: ffffffffa03b5200 RCX: 0000000000000000
 RDX: 0000000000001000 RSI: ffff88080fa7fe38 RDI: ffffffffa03b5000
 RBP: ffff88080fa7fe28 R08: 0000000000000010 R09: 0000000000000000
 R10: 0000000000000000 R11: 000000000000000f R12: ffffffffa03b5000
 R13: ffffffffa03b5008 R14: ffffffffa03b5200 R15: ffffffffa03b5000
 FS:  00007f6ae57ef740(0000) GS:ffff88101e7a0000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 0000000000404f70 CR3: 0000000ffed48000 CR4: 00000000001407e0
 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
 Stack:
  ffffffffa03b5200 ffff8810101e4800 ffff88080fa7fe70 ffffffff810d666c
  ffff88081e807300 000000002e0f2fbf 0000000000000000 ffff88100f257b00
  ffffffffa03b5008 ffff88080fa7ff48 ffff8810101e4800 ffff88080fa7fee0
 Call Trace:
  [&lt;ffffffff810d666c&gt;] m_show+0x19c/0x1e0
  [&lt;ffffffff811e4d7e&gt;] seq_read+0x16e/0x3b0
  [&lt;ffffffff812281ed&gt;] proc_reg_read+0x3d/0x80
  [&lt;ffffffff811c0f2c&gt;] vfs_read+0x9c/0x170
  [&lt;ffffffff811c1a58&gt;] SyS_read+0x58/0xb0
  [&lt;ffffffff81605829&gt;] system_call_fastpath+0x16/0x1b
 Code: 48 63 c2 83 c2 01 c6 04 03 29 48 63 d2 eb d9 0f 1f 80 00 00 00 00 48 63 d2 c6 04 13 2d 41 8b 0c 24 8d 50 02 83 f9 01 75 b2 eb cb &lt;0f&gt; 0b 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 41
 RIP  [&lt;ffffffff810d64c5&gt;] module_flags+0xb5/0xc0
  RSP &lt;ffff88080fa7fe18&gt;

    Consider the two processes running on the system.

    CPU 0 (/proc/modules reader)
    CPU 1 (loading/unloading module)

    CPU 0 opens /proc/modules, and starts displaying data for each module by
    traversing the modules list via fs/seq_file.c:seq_open() and
    fs/seq_file.c:seq_read().  For each module in the modules list, seq_read
    does

            op-&gt;start()  &lt;-- this is a pointer to m_start()
            op-&gt;show()   &lt;- this is a pointer to m_show()
            op-&gt;stop()   &lt;-- this is a pointer to m_stop()

    The m_start(), m_show(), and m_stop() module functions are defined in
    kernel/module.c. The m_start() and m_stop() functions acquire and release
    the module_mutex respectively.

    ie) When reading /proc/modules, the module_mutex is acquired and released
    for each module.

    m_show() is called with the module_mutex held.  It accesses the module
    struct data and attempts to write out module data.  It is in this code
    path that the above BUG_ON() warning is encountered, specifically m_show()
    calls

    static char *module_flags(struct module *mod, char *buf)
    {
            int bx = 0;

            BUG_ON(mod-&gt;state == MODULE_STATE_UNFORMED);
    ...

    The other thread, CPU 1, in unloading the module calls the syscall
    delete_module() defined in kernel/module.c.  The module_mutex is acquired
    for a short time, and then released.  free_module() is called without the
    module_mutex.  free_module() then sets mod-&gt;state = MODULE_STATE_UNFORMED,
    also without the module_mutex.  Some additional code is called and then the
    module_mutex is reacquired to remove the module from the modules list:

        /* Now we can delete it from the lists */
        mutex_lock(&amp;module_mutex);
        stop_machine(__unlink_module, mod, NULL);
        mutex_unlock(&amp;module_mutex);

This is the sequence of events that leads to the panic.

CPU 1 is removing dummy_module via delete_module().  It acquires the
module_mutex, and then releases it.  CPU 1 has NOT set dummy_module-&gt;state to
MODULE_STATE_UNFORMED yet.

CPU 0, which is reading the /proc/modules, acquires the module_mutex and
acquires a pointer to the dummy_module which is still in the modules list.
CPU 0 calls m_show for dummy_module.  The check in m_show() for
MODULE_STATE_UNFORMED passed for dummy_module even though it is being
torn down.

Meanwhile CPU 1, which has been continuing to remove dummy_module without
holding the module_mutex, now calls free_module() and sets
dummy_module-&gt;state to MODULE_STATE_UNFORMED.

CPU 0 now calls module_flags() with dummy_module and ...

static char *module_flags(struct module *mod, char *buf)
{
        int bx = 0;

        BUG_ON(mod-&gt;state == MODULE_STATE_UNFORMED);

and BOOM.

Acquire and release the module_mutex lock around the setting of
MODULE_STATE_UNFORMED in the teardown path, which should resolve the
problem.

Testing: In the unpatched kernel I can panic the system within 1 minute by
doing

while (true) do insmod dummy_module.ko; rmmod dummy_module.ko; done

and

while (true) do cat /proc/modules; done

in separate terminals.

In the patched kernel I was able to run just over one hour without seeing
any issues.  I also verified the output of panic via sysrq-c and the output
of /proc/modules looks correct for all three states for the dummy_module.

        dummy_module 12661 0 - Unloading 0xffffffffa03a5000 (OE-)
        dummy_module 12661 0 - Live 0xffffffffa03bb000 (OE)
        dummy_module 14015 1 - Loading 0xffffffffa03a5000 (OE+)

Signed-off-by: Prarit Bhargava &lt;prarit@redhat.com&gt;
Reviewed-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Signed-off-by: Rusty Russell &lt;rusty@rustcorp.com.au&gt;
Cc: stable@kernel.org
</content>
</entry>
</feed>
