summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
authorFrank Zago <fzago@cray.com>2015-02-01 21:52:15 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-07 17:32:33 +0800
commit7dd1107ad37a89e849f4fcbdb34fce775ce56db1 (patch)
tree7f57742ce73ed744c78db7546883edefa4257b0e /drivers/staging
parentb7fb222b8acb13672fe37ba1da79f75263781edf (diff)
staging/lustre/libcfs: protect kkuc_groups from write access
Since reg->kr_fp can be changed inside the foreach loop, kkuc_groups must be write protected, and not just read protected. This should fix the following oops, which could happen if two different threads simultaneously execute the function, and EPIPE is returned. PID: 24385 TASK: ffff88012da5f500 CPU: 1 COMMAND: "ldlm_cb00_056" #0 [ffff88012db55810] machine_kexec at ffffffff81038f3b #1 [ffff88012db55870] crash_kexec at ffffffff810c59f2 #2 [ffff88012db55940] oops_end at ffffffff8152b7f0 #3 [ffff88012db55970] no_context at ffffffff8104a00b #4 [ffff88012db559c0] __bad_area_nosemaphore at ffffffff8104a295 #5 [ffff88012db55a10] bad_area_nosemaphore at ffffffff8104a363 #6 [ffff88012db55a20] __do_page_fault at ffffffff8104aabf #7 [ffff88012db55b40] do_page_fault at ffffffff8152d73e #8 [ffff88012db55b70] page_fault at ffffffff8152aaf5 [exception RIP: fput+9] RIP: ffffffff8118a509 RSP: ffff88012db55c20 RFLAGS: 00010246 RAX: 00000000ffffffe0 RBX: ffff8800a8ea4fc0 RCX: 0000000000000000 RDX: ffffffffa03c9eb0 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffff88012db55c20 R8: 00000000ffffff0a R9: 00000000fffffffc R10: 0000000000000001 R11: 282064656c696166 R12: ffffffffa03c9c60 R13: ffff88005df240f8 R14: 0000000000000000 R15: ffff88013b4ca000 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #9 [ffff88012db55c28] libcfs_kkuc_group_put at ffffffffa0388044 [libcfs] [ptlrpc] Signed-off-by: frank zago <fzago@cray.com> Reviewed-on: http://review.whamcloud.com/11355 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5458 Reviewed-by: Patrick Farrell <paf@cray.com> Reviewed-by: James Simmons <uja.ornl@gmail.com> Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com> Signed-off-by: Oleg Drokin <oleg.drokin@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
index e2aa637abcf9..d9b7c6b69db4 100644
--- a/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
+++ b/drivers/staging/lustre/lustre/libcfs/kernel_user_comm.c
@@ -228,12 +228,12 @@ int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func,
if (kkuc_groups[group].next == NULL)
return 0;
- down_read(&kg_sem);
+ down_write(&kg_sem);
list_for_each_entry(reg, &kkuc_groups[group], kr_chain) {
if (reg->kr_fp != NULL)
rc = cb_func(reg->kr_data, cb_arg);
}
- up_read(&kg_sem);
+ up_write(&kg_sem);
return rc;
}