]> granicus.if.org Git - zfs/commitdiff
Add kpreempt_disable/enable around CPU_SEQID uses
authorMorgan Jones <mjones@rice.edu>
Mon, 19 Jun 2017 16:43:16 +0000 (16:43 +0000)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 19 Jun 2017 16:43:16 +0000 (09:43 -0700)
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 <behlendorf1@llnl.gov>
Signed-off-by: Morgan Jones <me@numin.it>
Closes #6239

module/icp/core/kcf_sched.c
module/zfs/dmu_object.c

index f9bcfe094e6b30f6f1901acc2e22907c1c488050..da2346f7ec21e9549252e6d3f75e76b61a943261 100644 (file)
@@ -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);
 
index cb861a196558aeba102c6d4d2b23a3f98944c16c..1c7b26d4becc17f46c253b1143683c4b627daffb 100644 (file)
@@ -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 {