内核cpumask_t,设置中断irq的cpu亲和性

中断亲和性使用cpumask_t来表示。

具体定义在/include/linux/cpumask.h:

/* Don't assign or return these: may not be this big! */
typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;

本质上就是一个long 类型的数组,数组多少和cpu数量相关。

//include/linux/types.h

#define DECLARE_BITMAP(name,bits) \
	unsigned long name[BITS_TO_LONGS(bits)]

 打印可阅读的方式如下:比如在128核的cpu下面,有四个long类型,总共128

[root@greatdb-m 518]# cat /proc/irq/518/
affinity_hint            effective_affinity_list  nvme0q2/                 smp_affinity_list        
effective_affinity       node                     smp_affinity             spurious                 
[root@greatdb-m 518]# cat /proc/irq/518/smp_affinity
00000000,00000000,00000000,ffff0000
[root@greatdb-m 518]# cat /proc/irq/518/smp_affinity_list 
16-31
[root@greatdb-m 518]# 

demo:

[root@phytium mod]# cat test.c 
#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/sched/task.h>
#include <linux/arm-smccc.h>
#include <linux/cpumask.h>

static int __init test_init(void)
{

	cpumask_t mask = {0};
	printk("%*pbl\n", cpumask_pr_args(&mask));
	printk("%*pb\n", cpumask_pr_args(&mask));
	cpumask_set_cpu(16,&mask);
	cpumask_set_cpu(127,&mask);
	printk("%*pbl\n", cpumask_pr_args(&mask));
	printk("%*pb\n", cpumask_pr_args(&mask));
	return 0;
}

static void __exit test_exit(void)
{
	printk(KERN_INFO "test_exit\n");
}

module_init(test_init);
module_exit(test_exit);


MODULE_LICENSE("GPL");

内核printk打印格式Documentation/core-api/printk-formats.rst:

bitmap and its derivatives such as cpumask and nodemask
-------------------------------------------------------

::

        %*pb    0779
        %*pbl   0,3-6,8-10

通过16进制显示:


[1651531.706196] 00000000,00000000,00000000,00000000
[1651531.706202] 16,127
[1651531.706207] 80000000,00000000,00000000,00010000

bit位 从低位到高位来代表某个cpu。比如16号cpu。0x10000对应二进制00010000000000000000。

设置中断亲和内核kernel/irq/proc.c:irq_affinity_list_proc_write。可以用ftrace来跟踪一下:

设置irq亲和性,脚本步骤:

[root@localhost ~]# cat ftrace.sh 
#!/bin/bash



debugfs=/sys/kernel/debug

echo nop > $debugfs/tracing/current_tracer

echo 0 > $debugfs/tracing/tracing_on

echo $$ > $debugfs/tracing/set_ftrace_pid

echo function_graph > $debugfs/tracing/current_tracer

#replace test_proc_show by your function name

echo irq_affinity_list_proc_write > $debugfs/tracing/set_graph_function

echo 1 > $debugfs/tracing/tracing_on

exec "$@"

[root@localhost ~]# ./ftrace.sh echo "1,3,6" > /proc/irq/57/smp_affinity_list 

查看trace:

[root@localhost 57]# cat /sys/kernel/tracing/trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 0)               |  irq_affinity_list_proc_write() {
 0)               |    write_irq_affinity.constprop.0.isra.0() {
 0)   0.687 us    |      PDE_DATA();
 0)               |      irq_can_set_affinity_usr() {
 0)   0.771 us    |        irq_to_desc();
 0)   2.146 us    |      }
 0)               |      memdup_user_nul() {
 0)               |        __kmalloc_track_caller() {
 0)   0.646 us    |          kmalloc_slab();
 0)   0.396 us    |          should_failslab();
 0)   2.604 us    |        }
 0)   3.479 us    |      }
 0)   0.667 us    |      kfree();
 0)               |      __irq_set_affinity() {
 0)   0.438 us    |        irq_to_desc();
 0)   0.667 us    |        _raw_spin_lock_irqsave();
 0)               |        irq_set_affinity_locked() {
 0)               |          irq_do_set_affinity() {
 0)               |            msi_domain_set_affinity() {
 0)               |              its_set_affinity() {
 0)   0.625 us    |                its_dec_lpi_count.isra.0();
 0)               |                its_select_cpu() {
 0)   0.812 us    |                  cpumask_pick_least_loaded();
 0)   1.875 us    |                }
 0)   0.375 us    |                its_inc_lpi_count.isra.0();
 0)   4.750 us    |              }
 0)   5.938 us    |            }
 0)   0.521 us    |            irq_set_thread_affinity();
 0)   7.687 us    |          }
 0)   8.541 us    |        }
 0)   0.375 us    |        _raw_spin_unlock_irqrestore();
 0) + 11.855 us   |      }
 0) + 22.895 us   |    }
 0) + 26.584 us   |  }

its_set_affinity函数在irq-gic-v3-its.c:还会调用irq_data_update_effective_affinity设置活动affinity。代表当前是那个核来接受中断。

[root@localhost ~]# cat /proc/irq/57/smp_affinity_list 
1,3,6

[root@localhost ~]# cat /proc/irq/57/effective_affinity_list 
3


 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古井无波 2024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值