Skip to content

Commit

Permalink
Add kpreempt_disable/enable around CPU_SEQID uses
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Morgan Jones <[email protected]>
Closes openzfs#6239
  • Loading branch information
numinit authored and behlendorf committed Jun 19, 2017
1 parent 0241e49 commit d9ad3fe
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 4 deletions.
7 changes: 5 additions & 2 deletions module/icp/core/kcf_sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
8 changes: 6 additions & 2 deletions module/zfs/dmu_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit d9ad3fe

Please sign in to comment.