Hi Jens, I've been going through smp_call_function_single_async() users and stumbled upon blk-softirq.c, which has: static int raise_blk_irq(int cpu, struct request *rq) { if (cpu_online(cpu)) { call_single_data_t *data = &rq->csd; data->func = trigger_softirq; data->info = rq; data->flags = 0; smp_call_function_single_async(cpu, data); return 0; } return 1; } What, if anything, guarantees rq->csd is not already in use at that time? The purpose of that CSD is to make the BLOCK_SOFTIRQ go, but there's plenty of other ways to tickle that, afaict. So if that races vs someone else, and that completes whatever was needed, then can't we get to raise_blk_irq() again, even though the csd is still enqueued? Worse; it has: data->flags = 0; so our early exit will not happen, even when it should.