// 向系统注册时钟事件设备
// 函数任务:
// 1.添加设备到clockevent_devices链表
// 2.通知tick device管理机制有clockevent设备注册
1.1 void clockevents_register_device(struct clock_event_device *dev)
{
unsigned long flags;
raw_spin_lock_irqsave(&clockevents_lock, flags);
//将设备添加到clockevent_devices链表
list_add(&dev->list, &clockevent_devices);
//向系统通知有新设备注册
clockevents_do_notify(CLOCK_EVT_NOTIFY_ADD, dev);
raw_spin_unlock_irqrestore(&clockevents_lock, flags);
}
// clockevent设备注册处理函数
// 调用路径:tick_notify->CLOCK_EVT_NOTIFY_ADD
// 函数任务:
// 1.确认设备服务于本cpu
// 2.如果设备非本cpu的local device
// 2.1 设置cpu的irq亲和性
// 2.2 如果本cpu已经绑定一个local device,并且二者服务的cpu相同,则忽略
// 3.如果本cpu已有local device,选择两者中更好的
// 3.1 优先选择支持单触发的
// 3.2 然后选择高rating的
// 4.如果本cpu使用的clockevent设备为广播设备,直接关闭
// 5.更新cpu的tick device为新tick device
// 6.启动tick device
// 7.异步通知周期时钟关于时钟事件设备的改变
// 注:如果不能设置为本cpu tick device的事件源,考虑其是否可以作为广播设备。
1.2 static int tick_check_new_device(struct clock_event_device *newdev)
{
struct clock_event_device *curdev;
struct tick_device *td;
int cpu, ret = NOTIFY_OK;
unsigned long flags;
raw_spin_lock_irqsave(&tick_device_lock, flags);
//检查设备是否服务于本cpu
cpu = smp_processor_id();
if (!cpumask_test_cpu(cpu, newdev->cpumask))
goto out_bc;
//当前cpu的tick_device
td = &per_cpu(tick_cpu_device, cpu);
curdev = td->evtdev;
//检查是否为本cpu的local device
// 如果设备只服务于本cpu,则为local device
if (!cpumask_equal(newdev->cpumask, cpumask_of(cpu))) {
//非local device,并且不能设置irq 亲和性,忽略
if (!irq_can_set_affinity(new
时间子系统12_clockevent设备注册
最新推荐文章于 2024-07-02 14:44:14 发布
本文详细介绍了Linux内核中时间子系统的clockevent设备注册过程,包括`clockevents_register_device`函数如何将设备添加到`clockevent_devices`链表,以及`tick_check_new_device`函数如何处理新设备注册,选择最佳的时钟事件设备。内容涵盖了设备的中断亲和性设置、设备选择策略以及广播设备的处理。
摘要由CSDN通过智能技术生成