Skip to content

Commit 770b1d2

Browse files
Davidlohr Buesoliu-song-6
authored andcommitted
md/raid5: play nice with PREEMPT_RT
raid_run_ops() relies on the implicitly disabled preemption for its percpu ops, although this is really about CPU locality. This breaks RT semantics as it can take regular (and thus sleeping) spinlocks, such as stripe_lock. Add a local_lock such that non-RT does not change and continues to be just map to preempt_disable/enable, but makes RT happy as the region will use a per-CPU spinlock and thus be preemptible and still guarantee CPU locality. Signed-off-by: Davidlohr Bueso <[email protected]> Signed-off-by: Song Liu <[email protected]>
1 parent 050f461 commit 770b1d2

File tree

2 files changed

+9
-6
lines changed

2 files changed

+9
-6
lines changed

drivers/md/raid5.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,10 +2215,9 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
22152215
struct r5conf *conf = sh->raid_conf;
22162216
int level = conf->level;
22172217
struct raid5_percpu *percpu;
2218-
unsigned long cpu;
22192218

2220-
cpu = get_cpu();
2221-
percpu = per_cpu_ptr(conf->percpu, cpu);
2219+
local_lock(&conf->percpu->lock);
2220+
percpu = this_cpu_ptr(conf->percpu);
22222221
if (test_bit(STRIPE_OP_BIOFILL, &ops_request)) {
22232222
ops_run_biofill(sh);
22242223
overlap_clear++;
@@ -2271,13 +2270,14 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request)
22712270
BUG();
22722271
}
22732272

2274-
if (overlap_clear && !sh->batch_head)
2273+
if (overlap_clear && !sh->batch_head) {
22752274
for (i = disks; i--; ) {
22762275
struct r5dev *dev = &sh->dev[i];
22772276
if (test_and_clear_bit(R5_Overlap, &dev->flags))
22782277
wake_up(&sh->raid_conf->wait_for_overlap);
22792278
}
2280-
put_cpu();
2279+
}
2280+
local_unlock(&conf->percpu->lock);
22812281
}
22822282

22832283
static void free_stripe(struct kmem_cache *sc, struct stripe_head *sh)
@@ -7052,6 +7052,7 @@ static int alloc_scratch_buffer(struct r5conf *conf, struct raid5_percpu *percpu
70527052
return -ENOMEM;
70537053
}
70547054

7055+
local_lock_init(&percpu->lock);
70557056
return 0;
70567057
}
70577058

drivers/md/raid5.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <linux/raid/xor.h>
66
#include <linux/dmaengine.h>
7+
#include <linux/local_lock.h>
78

89
/*
910
*
@@ -640,7 +641,8 @@ struct r5conf {
640641
* lists and performing address
641642
* conversions
642643
*/
643-
int scribble_obj_size;
644+
int scribble_obj_size;
645+
local_lock_t lock;
644646
} __percpu *percpu;
645647
int scribble_disks;
646648
int scribble_sectors;

0 commit comments

Comments
 (0)