blob: bb3ed488f7b5b26053e91dd3a5f02a0f2c472a70 [file] [log] [blame]
Jens Axboe75bb4622014-05-28 10:15:41 -06001/*
2 * CPU notifier helper code for blk-mq
3 *
4 * Copyright (C) 2013-2014 Jens Axboe
5 */
Jens Axboe320ae512013-10-24 09:20:05 +01006#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/init.h>
9#include <linux/blkdev.h>
10#include <linux/list.h>
11#include <linux/llist.h>
12#include <linux/smp.h>
13#include <linux/cpu.h>
14
15#include <linux/blk-mq.h>
16#include "blk-mq.h"
17
18static LIST_HEAD(blk_mq_cpu_notify_list);
Mike Galbraith2a26ebe2014-03-03 05:57:26 +010019static DEFINE_RAW_SPINLOCK(blk_mq_cpu_notify_lock);
Jens Axboe320ae512013-10-24 09:20:05 +010020
Paul Gortmakerf618ef72013-11-14 08:26:02 -070021static int blk_mq_main_cpu_notify(struct notifier_block *self,
22 unsigned long action, void *hcpu)
Jens Axboe320ae512013-10-24 09:20:05 +010023{
24 unsigned int cpu = (unsigned long) hcpu;
25 struct blk_mq_cpu_notifier *notify;
Jens Axboee814e712014-05-21 13:59:08 -060026 int ret = NOTIFY_OK;
Jens Axboe320ae512013-10-24 09:20:05 +010027
Mike Galbraith2a26ebe2014-03-03 05:57:26 +010028 raw_spin_lock(&blk_mq_cpu_notify_lock);
Jens Axboe320ae512013-10-24 09:20:05 +010029
Jens Axboee814e712014-05-21 13:59:08 -060030 list_for_each_entry(notify, &blk_mq_cpu_notify_list, list) {
31 ret = notify->notify(notify->data, action, cpu);
32 if (ret != NOTIFY_OK)
33 break;
34 }
Jens Axboe320ae512013-10-24 09:20:05 +010035
Mike Galbraith2a26ebe2014-03-03 05:57:26 +010036 raw_spin_unlock(&blk_mq_cpu_notify_lock);
Jens Axboee814e712014-05-21 13:59:08 -060037 return ret;
Jens Axboe320ae512013-10-24 09:20:05 +010038}
39
Jens Axboe320ae512013-10-24 09:20:05 +010040void blk_mq_register_cpu_notifier(struct blk_mq_cpu_notifier *notifier)
41{
42 BUG_ON(!notifier->notify);
43
Mike Galbraith2a26ebe2014-03-03 05:57:26 +010044 raw_spin_lock(&blk_mq_cpu_notify_lock);
Jens Axboe320ae512013-10-24 09:20:05 +010045 list_add_tail(&notifier->list, &blk_mq_cpu_notify_list);
Mike Galbraith2a26ebe2014-03-03 05:57:26 +010046 raw_spin_unlock(&blk_mq_cpu_notify_lock);
Jens Axboe320ae512013-10-24 09:20:05 +010047}
48
49void blk_mq_unregister_cpu_notifier(struct blk_mq_cpu_notifier *notifier)
50{
Mike Galbraith2a26ebe2014-03-03 05:57:26 +010051 raw_spin_lock(&blk_mq_cpu_notify_lock);
Jens Axboe320ae512013-10-24 09:20:05 +010052 list_del(&notifier->list);
Mike Galbraith2a26ebe2014-03-03 05:57:26 +010053 raw_spin_unlock(&blk_mq_cpu_notify_lock);
Jens Axboe320ae512013-10-24 09:20:05 +010054}
55
56void blk_mq_init_cpu_notifier(struct blk_mq_cpu_notifier *notifier,
Jens Axboee814e712014-05-21 13:59:08 -060057 int (*fn)(void *, unsigned long, unsigned int),
Jens Axboe320ae512013-10-24 09:20:05 +010058 void *data)
59{
60 notifier->notify = fn;
61 notifier->data = data;
62}
63
Jens Axboe320ae512013-10-24 09:20:05 +010064void __init blk_mq_cpu_init(void)
65{
Andrew Morton381d3ee2014-01-28 09:52:01 -070066 hotcpu_notifier(blk_mq_main_cpu_notify, 0);
Jens Axboe320ae512013-10-24 09:20:05 +010067}