理论分析
打印cpumask,函数如下:
5530 static ssize_t wq_unbound_cpumask_show(struct device *dev,
5531 struct device_attribute *attr, char *buf)
5532 {
5533 int written;
5534
5535 mutex_lock(&wq_pool_mutex);
5536 written = scnprintf(buf, PAGE_SIZE, "%*pb\n",
5537 cpumask_pr_args(wq_unbound_cpumask));
5538 mutex_unlock(&wq_pool_mutex);
5539
5540 return written;
5541 }
上面代码中,cpumask_pr_args 的宏定义如下:
30 /**
31 * cpumask_pr_args - printf args to output a cpumask
32 * @maskp: cpumask to be printed
33 *
34 * Can be used to provide arguments for '%*pb[l]' when printing a cpumask.
35 */
36 #define cpumask_pr_args(maskp) nr_cpu_ids, cpumask_bits(maskp)
%*pb[l]
是 Linux 内核中用来打印 cpumask 的特殊格式字符串
%*p
表示需要两个参数:宽度和指针
b
表示以位图(bitmap)格式打印
l
是可选的,表示使用列表格式而不是十六进制掩码格式
cpumask_pr_args(maskp)
宏展开后会产生两个参数:
nr_cpu_ids
:系统中cpu的数目
cpumask_bits(maskp)
:指向cpumask结构体中的位图的指针
举例
#include <linux/cpumask.h>
#include <linux/printk.h> // 用于 pr_info
void print_example_cpumask(void) {
cpumask_var_t mask;
// 动态分配一个 cpumask
if (!alloc_cpumask_var(&mask, GFP_KERNEL))
return;
// 设置 CPU 0、2、3
cpumask_clear(mask);
cpumask_set_cpu(0, mask);
cpumask_set_cpu(2, mask);
cpumask_set_cpu(3, mask);
// 打印 cpumask(十六进制位掩码格式)
pr_info("Hex mask: %*pb\n", cpumask_pr_args(mask));
// 打印 cpumask(列表格式)
pr_info("List format: %*pbl\n", cpumask_pr_args(mask));
// 释放 cpumask
free_cpumask_var(mask);
}
执行结果:
(假设系统有 4 个 CPU(nr_cpu_ids = 4))
Hex mask: 00000000,0000000d
List format: 0,2-3
实例解析:
%*pb(十六进制位掩码格式):
00000000,0000000d:
这是一个位掩码,每个十六进制数字代表 4 个 CPU 的状态(0 = 未设置,1 = 设置)。
0d(二进制 1101)表示 CPU 0、2、3 被设置(1),而 CPU 1 未被设置(0)。
前面的 00000000 是因为 nr_cpu_ids 可能较大(例如 64 位系统),但实际只有低 4 位有效。
%*pbl(列表格式):
0,2-3:
直接列出被设置的 CPU。
0 表示 CPU 0 被设置。
2-3 表示 CPU 2 和 CPU 3 被设置(连续的 CPU 用 - 连接)。