From d9ad3fea3bd0368b6af0b08ccc4de1b080e2bcb7 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Mon, 19 Jun 2017 16:43:16 +0000 Subject: [PATCH] Add kpreempt_disable/enable around CPU_SEQID uses In zfs/dmu_object and icp/core/kcf_sched, the CPU_SEQID macro should be surrounded by `kpreempt_disable` and `kpreempt_enable` calls to avoid a Linux kernel BUG warning. These code paths use the cpuid to minimize lock contention and is is safe to reschedule the process to a different processor at any time. Reviewed-by: Brian Behlendorf Signed-off-by: Morgan Jones Closes #6239 --- module/icp/core/kcf_sched.c | 7 +++++-- module/zfs/dmu_object.c | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/module/icp/core/kcf_sched.c b/module/icp/core/kcf_sched.c index f9bcfe094..da2346f7e 100644 --- a/module/icp/core/kcf_sched.c +++ b/module/icp/core/kcf_sched.c @@ -1306,8 +1306,11 @@ kcf_reqid_insert(kcf_areq_node_t *areq) int indx; crypto_req_id_t id; kcf_areq_node_t *headp; - kcf_reqid_table_t *rt = - kcf_reqid_table[CPU_SEQID & REQID_TABLE_MASK]; + kcf_reqid_table_t *rt; + + kpreempt_disable(); + rt = kcf_reqid_table[CPU_SEQID & REQID_TABLE_MASK]; + kpreempt_enable(); mutex_enter(&rt->rt_lock); diff --git a/module/zfs/dmu_object.c b/module/zfs/dmu_object.c index cb861a196..1c7b26d4b 100644 --- a/module/zfs/dmu_object.c +++ b/module/zfs/dmu_object.c @@ -59,10 +59,14 @@ dmu_object_alloc_dnsize(objset_t *os, dmu_object_type_t ot, int blocksize, dnode_t *dn = NULL; int dn_slots = dnodesize >> DNODE_SHIFT; boolean_t restarted = B_FALSE; - uint64_t *cpuobj = &os->os_obj_next_percpu[CPU_SEQID % - os->os_obj_next_percpu_len]; + uint64_t *cpuobj = NULL; int dnodes_per_chunk = 1 << dmu_object_alloc_chunk_shift; + kpreempt_disable(); + cpuobj = &os->os_obj_next_percpu[CPU_SEQID % + os->os_obj_next_percpu_len]; + kpreempt_enable(); + if (dn_slots == 0) { dn_slots = DNODE_MIN_SLOTS; } else {