1/* 2 * CPU notifier helper code for blk-mq 3 * 4 * Copyright (C) 2013-2014 Jens Axboe 5 */ 6#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); 19static DEFINE_RAW_SPINLOCK(blk_mq_cpu_notify_lock); 20 21static int blk_mq_main_cpu_notify(struct notifier_block *self, 22 unsigned long action, void *hcpu) 23{ 24 unsigned int cpu = (unsigned long) hcpu; 25 struct blk_mq_cpu_notifier *notify; 26 int ret = NOTIFY_OK; 27 28 raw_spin_lock(&blk_mq_cpu_notify_lock); 29 30 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 } 35 36 raw_spin_unlock(&blk_mq_cpu_notify_lock); 37 return ret; 38} 39 40void blk_mq_register_cpu_notifier(struct blk_mq_cpu_notifier *notifier) 41{ 42 BUG_ON(!notifier->notify); 43 44 raw_spin_lock(&blk_mq_cpu_notify_lock); 45 list_add_tail(¬ifier->list, &blk_mq_cpu_notify_list); 46 raw_spin_unlock(&blk_mq_cpu_notify_lock); 47} 48 49void blk_mq_unregister_cpu_notifier(struct blk_mq_cpu_notifier *notifier) 50{ 51 raw_spin_lock(&blk_mq_cpu_notify_lock); 52 list_del(¬ifier->list); 53 raw_spin_unlock(&blk_mq_cpu_notify_lock); 54} 55 56void blk_mq_init_cpu_notifier(struct blk_mq_cpu_notifier *notifier, 57 int (*fn)(void *, unsigned long, unsigned int), 58 void *data) 59{ 60 notifier->notify = fn; 61 notifier->data = data; 62} 63 64void __init blk_mq_cpu_init(void) 65{ 66 hotcpu_notifier(blk_mq_main_cpu_notify, 0); 67} 68