Commit aea9058801c0acfa2831af1714da412dfb0018c2
Committed by
Alasdair G Kergon
1 parent
5642b8a61a
Exists in
master
and in
7 other branches
dm: path selector use module refcount directly
Fix refcount corruption in dm-path-selector Refcounting with non-atomic ops under shared lock will corrupt the counter in multi-processor system and may trigger BUG_ON(). Use module refcount. # same approach as dm-target-use-module-refcount-directly.patch here # https://www.redhat.com/archives/dm-devel/2008-December/msg00075.html Typical oops: kernel BUG at linux-2.6.29-rc3/drivers/md/dm-path-selector.c:90! Pid: 11148, comm: dmsetup Not tainted 2.6.29-rc3-nm #1 dm_put_path_selector+0x4d/0x61 [dm_multipath] Call Trace: [<ffffffffa031d3f9>] free_priority_group+0x33/0xb3 [dm_multipath] [<ffffffffa031d4aa>] free_multipath+0x31/0x67 [dm_multipath] [<ffffffffa031d50d>] multipath_dtr+0x2d/0x32 [dm_multipath] [<ffffffffa015d6c2>] dm_table_destroy+0x64/0xd8 [dm_mod] [<ffffffffa015b73a>] __unbind+0x46/0x4b [dm_mod] [<ffffffffa015b79f>] dm_swap_table+0x60/0x14d [dm_mod] [<ffffffffa015f963>] dev_suspend+0xfd/0x177 [dm_mod] [<ffffffffa0160250>] dm_ctl_ioctl+0x24c/0x29c [dm_mod] [<ffffffff80288cd3>] ? get_page_from_freelist+0x49c/0x61d [<ffffffffa015f866>] ? dev_suspend+0x0/0x177 [dm_mod] [<ffffffff802bf05c>] vfs_ioctl+0x2a/0x77 [<ffffffff802bf4f1>] do_vfs_ioctl+0x448/0x4a0 [<ffffffff802bf5a0>] sys_ioctl+0x57/0x7a [<ffffffff8020c05b>] system_call_fastpath+0x16/0x1b Cc: stable@kernel.org Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Showing 1 changed file with 3 additions and 18 deletions Side-by-side Diff
drivers/md/dm-path-selector.c
... | ... | @@ -17,9 +17,7 @@ |
17 | 17 | |
18 | 18 | struct ps_internal { |
19 | 19 | struct path_selector_type pst; |
20 | - | |
21 | 20 | struct list_head list; |
22 | - long use; | |
23 | 21 | }; |
24 | 22 | |
25 | 23 | #define pst_to_psi(__pst) container_of((__pst), struct ps_internal, pst) |
... | ... | @@ -45,12 +43,8 @@ |
45 | 43 | |
46 | 44 | down_read(&_ps_lock); |
47 | 45 | psi = __find_path_selector_type(name); |
48 | - if (psi) { | |
49 | - if ((psi->use == 0) && !try_module_get(psi->pst.module)) | |
50 | - psi = NULL; | |
51 | - else | |
52 | - psi->use++; | |
53 | - } | |
46 | + if (psi && !try_module_get(psi->pst.module)) | |
47 | + psi = NULL; | |
54 | 48 | up_read(&_ps_lock); |
55 | 49 | |
56 | 50 | return psi; |
... | ... | @@ -84,11 +78,7 @@ |
84 | 78 | if (!psi) |
85 | 79 | goto out; |
86 | 80 | |
87 | - if (--psi->use == 0) | |
88 | - module_put(psi->pst.module); | |
89 | - | |
90 | - BUG_ON(psi->use < 0); | |
91 | - | |
81 | + module_put(psi->pst.module); | |
92 | 82 | out: |
93 | 83 | up_read(&_ps_lock); |
94 | 84 | } |
... | ... | @@ -134,11 +124,6 @@ |
134 | 124 | if (!psi) { |
135 | 125 | up_write(&_ps_lock); |
136 | 126 | return -EINVAL; |
137 | - } | |
138 | - | |
139 | - if (psi->use) { | |
140 | - up_write(&_ps_lock); | |
141 | - return -ETXTBSY; | |
142 | 127 | } |
143 | 128 | |
144 | 129 | list_del(&psi->list); |