加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

linux內(nèi)核中打印cpumask的方法總結(jié)

04/24 11:50
4445
閱讀需 9 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

哈嘍,大家好,我是LittleG。

前言

Linux內(nèi)核中,CPU掩碼(cpumask)用于表示一組CPU編號(hào),常用于描述進(jìn)程或任務(wù)的親和性、中斷或定時(shí)器的分配范圍等場景。

如下類似打印:

Task scheduled on CPUs: 0-3,7

下面就記錄一些常用的打印cpumask的方法。

正文

1、printk?與?cpumask_printk?宏:

Linux內(nèi)核中最常用的打印接口是printk函數(shù),可以接收格式化字符串和參數(shù),類似用戶空間的printf。同時(shí)為了便于打印cpumask,內(nèi)核還提供了一些輔助宏,如cpumask_printk,可以接受一個(gè)cpumask_t類型的變量和一個(gè)格式化字符串作為參數(shù)。

例如:

#include <linux/cpumask.h>
#include <linux/kernel.h>

void print_cpu_mask(cpumask_t *mask)
{
    printk(KERN_INFO "CPU mask: %*pbn", cpumask_bits(mask)[0]);
    // 或者使用 cpumask_printk 宏
    cpumask_printk("CPU mask: ", mask);
}

說明: 上述代碼中,%*pb是一種特殊的格式化符,用于打印位掩碼(cpumask_t本質(zhì)上是一個(gè)位掩碼)。cpumask_bits(mask)[0]獲取掩碼的第一個(gè)長整型元素,用于指定要打印的位數(shù)。cpumask_printk宏則提供了一種更直接的方式,它內(nèi)部會(huì)處理掩碼的格式化輸出。

2、dump_stack?和?dump_cpu_mask

當(dāng)需要在內(nèi)核崩潰報(bào)告或調(diào)試信息中包含當(dāng)前CPU掩碼時(shí),可以調(diào)用dump_stack()函數(shù),它會(huì)自動(dòng)打印當(dāng)前CPU的標(biāo)識(shí)。如果需要更詳細(xì)地打印某個(gè)cpumask_t,可以結(jié)合dump_cpu_mask()函數(shù),通常與dump_stack()一起使用,用于在內(nèi)核oops堆棧跟蹤中輸出CPU掩碼。

例如:

#include <linux/dump_stack.h>
#include <linux/kernel.h>

void dump_cpu_mask_example(cpumask_t *mask)
{
    dump_stack();
    dump_cpu_mask(mask);
}

調(diào)用dump_cpu_mask_example()時(shí),會(huì)在內(nèi)核日志中看到堆棧跟蹤信息以及跟隨其后的CPU掩碼打印。

3、直接訪問cpumask_t的位:

對于更精細(xì)的控制或特殊情況,可以直接遍歷cpumask_t的位數(shù)組,并使用printk打印其中的每一位。雖然cpumask_printk通常已能滿足需求,但cpumask_t 提供了更大的靈活性。

例如:

#include <linux/bitops.h>
#include <linux/cpumask.h>
#include <linux/kernel.h>

void print_cpu_mask_manual(cpumask_t *mask)
{
    int cpu;

    for_each_cpu(cpu, mask) {
        printk(KERN_INFO "CPU %d is set in the mask.n", cpu);
    }
}

上述代碼使用for_each_cpu宏遍歷cpumask_t中的每個(gè)已置位CPU,并使用printk打印其編號(hào)。

4、cpumask_pr_args?宏

cpumask_pr_args?可以直觀可讀的形式輸出?cpumask_t?中包含的 CPU 核心編號(hào)列表,并將其作為函數(shù)參數(shù)傳遞給其他內(nèi)核日志打印函數(shù)。這樣做的好處是能夠方便地將?cpumask_t?的內(nèi)容嵌入到其他日志消息中,而不必單獨(dú)調(diào)用cpumask_printk或者手動(dòng)構(gòu)建包含 CPU 列表的字符串。

例如:

// https://elixir.bootlin.com/linux/latest/source/include/linux/cpumask.h#L36
/**
 * cpumask_pr_args - printf args to output a cpumask
 * @maskp: cpumask to be printed
 *
 * Can be used to provide arguments for '%*pb[l]' when printing a cpumask.
 */
#define cpumask_pr_args(maskp)   nr_cpu_ids, cpumask_bits(maskp)

// https://elixir.bootlin.com/linux/latest/source/arch/arm64/kernel/cpufeature.c#L1521
static ssize_t aarch32_el0_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
{
        const struct cpumask *mask = system_32bit_el0_cpumask();

        return sysfs_emit(buf, "%*pbln", cpumask_pr_args(mask));
}
static const DEVICE_ATTR_RO(aarch32_el0);

說明:

%*pbl?是格式占位符,用于接收?cpumask_pr_args?生成的 CPU 核心列表字符串。

%*pbl?是內(nèi)核日志特有的格式說明符,其中?*?表示寬度由參數(shù)決定,pbl?表示以空格分隔的 CPU 核心列表。

cpumask_pr_args?提供了一種便捷的方式來將?cpumask_t?的內(nèi)容以方便肉眼可讀的形式嵌入到日志消息中,通過使用?%*pbl?格式說明符與內(nèi)核日志打印函數(shù)(如?pr_info(),?pr_debug(),?pr_err()?等)配合使用,可以清晰地記錄與 CPU 核心關(guān)聯(lián)的操作情況。

總結(jié),具體開發(fā)過程中選擇哪種打印方法取決于具體的需求和調(diào)試環(huán)境。在大多數(shù)情況下,直接使用cpumask_printk宏就可以滿足打印CPU掩碼的需求了。

下期見~

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊 ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
MX25R8035FZUIL0 1 Macronix International Co Ltd Flash, 2MX4, PDSO8, USON-8
暫無數(shù)據(jù) 查看
APT1608SECK/J3-PRV 1 Kingbright LED RED CLEAR 0603 SMD
$0.53 查看
88E1512-A0-NNP2C000 1 Marvell Technology Group Ltd Ethernet Transceiver, QFN-56
暫無數(shù)據(jù) 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

記錄和分享C/C++、Linux、ARM、Android、IoT相關(guān)知識(shí)。技術(shù)相伴于生活和成長,愿你我永為少年,心中有火,眼中有光,始保熱情。