目录
NODEMASK 原理
NODEMASK 作为内核基础数据结构,常用于统计当前 Online/Possible Online NUMA NODE 的数量、判断 NUMA NODE 是否包含内存、判断 NUMA NODE 是否与 CPU 进行绑定等,NODEMASK 作为 NUMA 子系统不可或缺的一部分,为内核和其他子系统提供了 NUMA NODE 的多种信息,首先来看一下 NODEMASK 定义:
#ifdef CONFIG_NODES_SHIFT
#define NODES_SHIFT CONFIG_NODES_SHIFT
#else
#define NODES_SHIFT 0
#endif
#define MAX_NUMNODES (1 << NODES_SHIFT)
typedef struct { DECLARE_BITMAP( bits, MAX_NUMNODES) ; } nodemask_t;
在支持多 NUMA NODE 的架构体系中,内核可以最多支持 MAX_NUMNODES 个 NUMA NODE, NODEMASK 基于 Bitmap 机制,将每个 NUMA NODE 通过 bitmap 中的一个 bit 进行维护,因此定义了 NODEMASK 逻辑结构,每个 NUMA NODE 对应了 NODEMASK 中的一个 bit,也可以称为 node,通过 node 的置位或清零来维护指定信息。
node_states
在 NUMA 子系统中,内核为了更好的维护 NUMA NODE 与 CPU/Memory/Online/Offline 等信息,定义了一系列的 NODEMASK 来维护这些关系。NUMA 子系统定义了名为 node_states 的 NODEMASK 数组,其定义如下:
在 node_states[] 数组中定义了多种类型的 NODEMASK, 例如 N_ONLINE 对应的 NODEMASK 用于描述当前在线的 NUMA NODE 情况,只要某个 NUMA NODE 在线/在使用中,那么该 NUMA NODE ID 在 N_ONLINE NODEMASK 指定的 node 就置位,以此表示该 NUMA NODE 正在使用/在线. 同理, N_POSSIBLE 对应的 NODEMASK 用于表示正在线上或可能上线的 NUMA NODE 信息; N_MEMORY 用于表示已经具有高端内存或者普通内存的 NUMA NODE; N_HIGH_MEMORY 用于表示已经包含高端内存的 NUMA NODE; N_NORMAL_MEMORY 用于表示已经包含普通物理内存的 NUMA NODE 信息; N_CPU 则表示已经与 CPU 进行绑定的 NUMA NODE 信息。NODEMASK 机制提供了一系列的函数用于便捷的从 node_states[] 数组中获得 NUMA NODE 相关信息,开发者可以参考以下章节进一步了解:
NODEMASK 源码分析及实例运用
NODEMASK 不仅提供了维护 NUMA NODE 相关的信息,还提供了一整套的 NUMA NODE 运算机制,便于动态调整 NUMA NODE 的相关数据,具体可以参考以下章节:
NODEMASK 使用
开发者可以通过了解 NODEMASK 中技术实现细节,以及 NODEMASK 实践,可以参考以下章节:
NODEMASK 实践
NODEMASK 源码分析及实例运用
NODEMASK 使用
NODEMASK 机制提供了一套完整的接口,内核和其他子系统可以通过这套接口获得所需的功能,本节用于介绍如何使用 NODEMASK.
NODEMASK 基础逻辑操作
node_states
NODEMASK 实践
实践准备
本实践只支持多种架构,但在支持 NUMA 架构的进行实践最优,目前 BiscuitOS 实践支持 NUMA 的架构包括 X86_64 架构和 ARM64 架构. 本文以在 X86_64 架构中实践为例. 首先开发者需要搭建基于 X86_64 架构的 linux 5.0 实践环境,请参考如下问题:
> BiscuitOS Linux 5.0 X86_64 Usermanual
> BiscuitOS Linux 5.0 ARM64 Usermanual
实践部署
在部署完毕开发环境之后,实践过程中由于要构建多 NUMA NODE 的情况,因此需要修改 BiscuitOS 的启动参数,参数位于 RunBiscuitOS.sh 节本中:
BiscuitOS/output/linux-5.0-i386/RunBiscuitOS.sh
如上图,在 BiscuitOS 启动命令中需要添加描述 NUMA NODE 的信息:
-object memory-backend-ram,id= mem0,size= 512M \
-numa node,memdev= mem0,cpus= 0-1,nodeid= 0 \
该命令用于创建一个独立的 NUMA NODE, 其包含了 512M 物理内存,并将 CPU 0 和 CPU 1 绑定到这个 NUMA NODE 上。开发者可以参考上面参数向 BiscuitOS 中添加一个或者多个 NUMA NODE.
实践执行
环境部署完毕之后,开发者可以 BiscuitOS 代码库中部署并安装多个 NODEMASK 实例进行实践,本节通过一个例子展示实例的使用办法,首先使用如下命令:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
开发者可以任意勾选一个实例进行实践,例如勾选 “first_ndoe”, 勾选完毕之后执行如下命令:
cd BiscuitOS/output/linux-5.0-x86_64/package/first_node-default
make download
make
make install
make pack
make run
通过上面的命令之后,可以看到 “first_node” 的实例通过一个模块被加载到内核执行,开发者可以使用该方法对 NODEMASK 进行实践. 更多实践细节,可以参考如下文档:
独立内核模块代码 – 独立程序开发办法
NODEMASK 源码分析及运用
node_states
在 NUMA 子系统中,内核为了更好的维护 NUMA NODE 与 CPU/Memory/Online/Offline 等信息,定义了一系列的 NODEMASK 来维护这些关系。NUMA 子系统定义了名为 node_states 的 NODEMASK 数组,其定义如下:
在 node_states[] 数组中定义了多种类型的 NODEMASK, 例如 N_ONLINE 对应的 NODEMASK 用于描述当前在线的 NUMA NODE 情况,只要某个 NUMA NODE 在线/在使用中,那么该 NUMA NODE ID 在 N_ONLINE NODEMASK 指定的 node 就置位,以此表示该 NUMA NODE 正在使用/在线. 同理, N_POSSIBLE 对应的 NODEMASK 用于表示正在线上或可能上线的 NUMA NODE 信息; N_MEMORY 用于表示已经具有高端内存或者普通内存的 NUMA NODE; N_HIGH_MEMORY 用于表示已经包含高端内存的 NUMA NODE; N_NORMAL_MEMORY 用于表示已经包含普通物理内存的 NUMA NODE 信息; N_CPU 则表示已经与 CPU 进行绑定的 NUMA NODE 信息。NODEMASK 机制提供了一系列的函数用于便捷的从 node_states[] 数组中获得 NUMA NODE 相关信息。
NODEMASK 作为内核基础数据结构,常用于统计当前 Online/Possible Online NUMA NODE 的数量、判断 NUMA NODE 是否包含内存、判断 NUMA NODE 是否与 CPU 进行绑定等,NODEMASK 作为 NUMA 子系统不可或缺的一部分,为内核和其他子系统提供了 NUMA NODE 的多种信息,首先来看一下 NODEMASK 定义:
#ifdef CONFIG_NODES_SHIFT
#define NODES_SHIFT CONFIG_NODES_SHIFT
#else
#define NODES_SHIFT 0
#endif
#define MAX_NUMNODES (1 << NODES_SHIFT)
typedef struct { DECLARE_BITMAP( bits, MAX_NUMNODES) ; } nodemask_t;
在支持多 NUMA NODE 的架构体系中,内核可以最多支持 MAX_NUMNODES 个 NUMA NODE, NODEMASK 基于 Bitmap 机制,将每个 NUMA NODE 通过 bitmap 中的一个 bit 进行维护,因此定义了 NODEMASK 逻辑结构,每个 NUMA NODE 对应了 NODEMASK 中的一个 bit,也可以称为 node,通过 node 的置位或清零来维护指定信息。
nr_online_nodes
int nr_online_nodes = 1;
nr_online_nodes 用于描述系统中在线的 NUMA NODE 个数.
node_online_map
#define node_online_map node_states[N_ONLINE]
node_online_map 用于描述 NUMA 子系统中在线 NUMA NODE 的 NODEMASK.
node_possible_map
#define node_possible_map node_states[N_POSSIBLE]
node_possible_map 用于描述 NUMA 子系统中可能在线 NUMA NODE 的 NODEMASK.
first_online_node
#define first_online_node first_node(node_states[N_ONLINE])
first_online_node 用于描述第一个在线的 NUMA NODE。
first_memory_node
#define first_memory_node first_node(node_states[N_MEMORY])
first_online_node 用于描述第一个包含内存的 NUMA NODE。
node_possible
#define node_possible(node) node_state((node), N_POSSIBLE)
node_possible() 函数用于判断指定的 NUMA NODE 是否可能上线,如果可能则返回 true,反之返回 false。函数通过 N_POSSIBLE 标志和调用 node_state() 函数判断对应的的 node 是否置位,如果置位则表示 NUMA NODE 可能在线. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_possible --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_possible
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* NUMA Statistic */
printk ( "The number of online nodes: %d \n " , num_online_nodes ());
printk ( "The number of possible nodes: %d \n " , num_possible_nodes ());
if ( node_online ( nid ))
printk ( "The NUMA NODE %d is online. \n " , nid );
if ( node_possible ( nid ))
printk ( "The NUMA NODE %d is possible online. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod num_online_nodes-default.ko
num_online_nodes_default: loading out-of-tree module taints kernel.
The number of online nodes: 1
The number of possible nodes: 1
The NUMA NODE 0 is online.
The NUMA NODE 0 is possible online.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
node_state
node_online
#define node_online(node) node_state((node), N_ONLINE)
node_online() 函数用于判断 NUMA NODE ID 对应的 NUMA NODE 是否在线,如果在线则返回 true,反之返回 false。函数通过 N_ONLINE 标志和调用 node_state() 函数从 node_states[] 数组中判断对应的 node 是否置位,如果置位,那么对应的 NUMA NODE 就在线,反之返回 false. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_online --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_online
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* NUMA Statistic */
printk ( "The number of online nodes: %d \n " , num_online_nodes ());
printk ( "The number of possible nodes: %d \n " , num_possible_nodes ());
if ( node_online ( nid ))
printk ( "The NUMA NODE %d is online. \n " , nid );
if ( node_possible ( nid ))
printk ( "The NUMA NODE %d is possible online. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod num_online_nodes-default.ko
num_online_nodes_default: loading out-of-tree module taints kernel.
The number of online nodes: 1
The number of possible nodes: 1
The NUMA NODE 0 is online.
The NUMA NODE 0 is possible online.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
node_state
num_possible_nodes
#define num_possible_nodes() num_node_state(N_POSSIBLE)
num_possible_nodes() 函数用于获得当前系统中可能在线的 NUMA NODE 数量。函数通过 N_POSSIBLE 标志和调用 num_node_state() 函数从 node_states[] 数组中获得当前可能在线的 NUMA NODE 数量。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] num_possible_nodes --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: num_possible_nodes
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* NUMA Statistic */
printk ( "The number of online nodes: %d \n " , num_online_nodes ());
printk ( "The number of possible nodes: %d \n " , num_possible_nodes ());
if ( node_online ( nid ))
printk ( "The NUMA NODE %d is online. \n " , nid );
if ( node_possible ( nid ))
printk ( "The NUMA NODE %d is possible online. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod num_online_nodes-default.ko
num_online_nodes_default: loading out-of-tree module taints kernel.
The number of online nodes: 1
The number of possible nodes: 1
The NUMA NODE 0 is online.
The NUMA NODE 0 is possible online.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
num_node_state
num_online_nodes
#define num_online_nodes() num_node_state(N_ONLINE)
num_online_nodes() 函数用于获得当前在线的 NUMA NODE 数量。函数通过 N_ONLINE 标志和调用 num_node_state() 函数从 node_states[] 数组中获得当前在线 NUMA NODE 的数量。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] num_online_nodes --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: num_online_nodes
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* NUMA Statistic */
printk ( "The number of online nodes: %d \n " , num_online_nodes ());
printk ( "The number of possible nodes: %d \n " , num_possible_nodes ());
if ( node_online ( nid ))
printk ( "The NUMA NODE %d is online. \n " , nid );
if ( node_possible ( nid ))
printk ( "The NUMA NODE %d is possible online. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod num_online_nodes-default.ko
num_online_nodes_default: loading out-of-tree module taints kernel.
The number of online nodes: 1
The number of possible nodes: 1
The NUMA NODE 0 is online.
The NUMA NODE 0 is possible online.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
num_node_state
node_set_online
node_set_online() 函数用于将指定的 NUMA NODE 上线。参数 nid 指向需要上线的 NUMA NODE. 此处所说的上线仅仅是将 NODE NODE 信息添加到系统在线 NUMA NODE 信息里。函数首先通过 N_ONLINE 标志和调用 node_set_online() 函数将对应的 NUMA NODE 标记为 online, 然后调用 num_node_state() 函数将当前在线的 NODE NODE 数量更新到 nr_online_nodes. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_set_online --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_set_online
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* Offline NUMA NODE */
node_set_offline ( nid );
/* Check NUMA NODE state */
if ( ! node_state ( nid , N_ONLINE ))
printk ( "Warning NUMA NODE %d offline! \n " , nid );
/* Online NUMA NODE */
node_set_online ( nid );
/* Check NUMA NODE state */
if ( node_state ( nid , N_ONLINE ))
printk ( "NUMA NODE %d online! \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_set_online-default.ko
node_set_online_default: loading out-of-tree module taints kernel.
Warning NUMA NODE 0 offline!
NUMA NODE 0 online!
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
num_node_state
node_set_state
node_set_offline
node_set_offline() 函数用于将指定的 NUMA NODE 下线。参数 nid 指向指定的 NUMA NODE. 这里所谓的下线仅仅是将指定的 NUMA NODE 从 node_states[N_ONLINE] NODEMASK 中对应 node 清零,以此从资源统计上达到减少的目的。函数首先通过 N_ONLINE 标志和 node_clear_state() 函数将对应的 NODEMASK 清零,然后再调用 num_node_state() 函数将当前在线的 NUMA NODE 信息更新到 nr_online_nodes 变量里. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_set_offline --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_set_offline
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* Offline NUMA NODE */
node_set_offline ( nid );
/* Check NUMA NODE state */
if ( ! node_state ( nid , N_ONLINE ))
printk ( "Warning NUMA NODE %d offline! \n " , nid );
/* Online NUMA NODE */
node_set_online ( nid );
/* Check NUMA NODE state */
if ( node_state ( nid , N_ONLINE ))
printk ( "NUMA NODE %d online! \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_set_offline-default.ko
node_set_offline_default: loading out-of-tree module taints kernel.
Warning NUMA NODE 0 offline!
NUMA NODE 0 online!
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
node_clear_state
num_node_state
next_memory_node
next_memory_node() 函数用于获得当前 NUMA NODE 之后包含物理内存的 NUMA NODE ID. 参数 nid 指向当前 NUMA NODE ID. 函数首先通过 N_MEMORY 标志从 node_states[] 数组中获得物理内存相关的 NODEMASK, 接着函数调用 next_node() 函数从当前 NUMA NODE ID 开始查找下一个置位的 node,找到的 ndoe 就是下一个包含物理内存的 NUMA NODE ID. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] next_memory_node --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: next_memory_node
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid ;
/* Next online NUMA NODE */
nid = next_memory_node ( 0 );
if ( nid == MAX_NUMNODES )
printk ( "Only NUMA NODE 0 contain memory \n " );
else
printk ( "The next node which contain memory for NUMA NODE 0: %d \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod next_memory_node-default.ko
next_memory_node_default: loading out-of-tree module taints kernel.
Only NUMA NODE 0 contain memory
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
next_node
next_online_node
next_online_node() 函数用于获得指定 NUMA NODE 之后在线的 NUMA NODE ID. 参数 nid 指向当前 NUMA NODE ID. 函数首先通过 N_ONLINE 标志从 node_states[] 数组中获得在线 NUMA NODE 的 NODEMASK,然后通过 next_node() 函数从 node 参数处开始,查找对应的 NODEMASK 下一个置位的 node,找到的 node 就是下一个在线的 NUMA NODE. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] next_online_node --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: next_online_node
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid ;
/* Next online NUMA NODE */
nid = next_online_node ( 0 );
if ( nid == MAX_NUMNODES )
printk ( "Only NUMA NODE 0 \n " );
else
printk ( "The next online node for NUMA NODE 0: %d \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod next_online_node-default.ko
next_online_node_default: loading out-of-tree module taints kernel.
Only NUMA NODE 0
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
next_node
for_each_node_state
for_each_node_state() 函数用于遍历具有某类资源的 NUMA NODE. 参数 __node 用于遍历时存储 NUMA NODE ID,参数 __state 用于指明某类资源。函数首先通过 __state 参数从 node_states[] 数组中获得某类资源对应的 NODEMASK, 接着调用 for_each_node_mask() 函数遍历该 NODEMASK 上所有置位的 node,以此遍历具有该类资源的 NUMA NODE. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] for_each_node_state --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: for_each_node_state
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid ;
/* Iterate special resource infomation */
for_each_node_state ( nid , N_CPU )
printk ( "NUMA NODE %d contains one or more CPUs. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod for_each_node_state-default.ko
for_each_node_state_default: loading out-of-tree module taints kernel.
NUMA NODE 0 contains one or more CPUs.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
for_each_node_mask
num_node_state
num_node_state() 函数用于判断已经获得某类资源的 NUMA NODE 数量。参数 state 用于指明资源的种类。函数首先通过 state 参数从 node_states[] 数组中获得指定的 NODEMASK, 然后调用 nodes_weight() 函数判断该 NODEMASK 中置位 node 的数量,以此获得该类资源 NUMA NODE 的数量。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] num_node_state --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: num_node_state
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
printk ( "Number of node: \n " );
printk ( "Online-Node: %d \n " , num_node_state ( N_ONLINE ));
printk ( "Possible Online: %d \n " , num_node_state ( N_POSSIBLE ));
printk ( "Normal Memory: %d \n " , num_node_state ( N_NORMAL_MEMORY ));
printk ( "High/Normal Memory: %d" , num_node_state ( N_HIGH_MEMORY ));
printk ( "Memory: %d \n " , num_node_state ( N_MEMORY ));
printk ( "CPU: %d \n " , num_node_state ( N_CPU ));
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod num_node_state-default.ko
num_node_state_default: loading out-of-tree module taints kernel.
Number of node:
Online-Node: 1
Possible Online: 1
Normal Memory: 1
High/Normal Memory: 1
Memory: 1
CPU: 1
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_weight
node_clear_state
node_clear_state() 函数用于清理 NUMA NODE 指定资源的信息。参数 node 指明 NUMA NODE ID, 参数 state 指明某类资源。函数首先通过 state 参数从 node_states[] 数组中获得对应资源的 NODEMASK, 接着函数调用 __node_clear() 函数将对应的 node 清除。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_clear_state --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_clear_state
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* Node clear state */
node_clear_state ( nid , N_CPU );
/* Check CPU State */
if ( ! node_state ( nid , N_CPU ))
printk ( "NUMA NODE %d doesn't contain any CPU. \n " , nid );
/* Node set state */
node_set_state ( nid , N_CPU );
/* Check CPU State */
if ( node_state ( nid , N_CPU ))
printk ( "NUMA NODE %d contains one or more CPUs. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_clear_state-default.ko
node_clear_state_default: loading out-of-tree module taints kernel.
NUMA NODE 0 doesn't contain any CPU.
NUMA NODE 0 contains one or more CPUs.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
__node_clear
node_set_state
node_set_state() 函数用于设置 NUMA NODE 指定资源信息。参数 node 指明 NUMA NODE ID, 参数 state 指明资源的种类. 函数首先通过 state 参数从 node_states[] 数组中获得指定资源对应的 NODEMASK, 然后通过 __node_set() 函数将指定的 ndoe 置位,以此达到 NUMA NODE 具有某类资源. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_set_state --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_set_state
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* Node clear state */
node_clear_state ( nid , N_CPU );
/* Check CPU State */
if ( ! node_state ( nid , N_CPU ))
printk ( "NUMA NODE %d doesn't contain any CPU. \n " , nid );
/* Node set state */
node_set_state ( nid , N_CPU );
/* Check CPU State */
if ( node_state ( nid , N_CPU ))
printk ( "NUMA NODE %d contains one or more CPUs. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_set_state-default.ko
node_set_state_default: loading out-of-tree module taints kernel.
NUMA NODE 0 doesn't contain any CPU.
NUMA NODE 0 contains one or more CPUs.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
__node_set
node_state
node_state() 函数用于读取指定 NUMA NODE 的信息,参数 node 指明 NUMA NODE ID, state 参数用于指明读取信息的类型。在 NUMA 子系统中,将 NUMA 相关的资源信息存储在 node_states[] 数组中,函数通过从该数组中获取不同类型的信息,每种信息使用 NODEMASK 进行维护,函数使用 node_isset() 函数判断指定 NUMA NODE 在该 NODEMASK 上是否置位,以此获得 NUMA NODE 是否已经具备该信息。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_state --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_state
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
int nid = numa_node_id ();
/* Check online */
if ( node_state ( nid , N_ONLINE ))
printk ( "NUMA NODE %d has online. \n " , nid );
else
printk ( "NUMA NODE %d has offline. \n " , nid );
/* Check possible online */
if ( node_state ( nid , N_POSSIBLE ))
printk ( "NUMA NODE %d could become online at some point. \n " , nid );
/* Check normal momory */
if ( node_state ( nid , N_NORMAL_MEMORY ))
printk ( "NUMA NODE %d has regular memory. \n " , nid );
/* Check Highmem memory */
if ( node_state ( nid , N_HIGH_MEMORY ))
printk ( "NUMA NODE %d has regular or high memory. \n " , nid );
/* Check memory */
if ( node_state ( nid , N_MEMORY ))
printk ( "NUMA NODE %d has memory (regular/high/movable) \n " , nid );
/* Check CPU */
if ( node_state ( nid , N_CPU ))
printk ( "NUMA NODE %d has one or more CPUs. \n " , nid );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_state-default.ko
node_state_default: loading out-of-tree module taints kernel.
NUMA NODE 0 has online.
NUMA NODE 0 could become online at some point.
NUMA NODE 0 has regular memory.
NUMA NODE 0 has regular or high memory.
NUMA NODE 0 has memory ( regular/high/movable)
NUMA NODE 0 has one or more CPUs.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
for_each_node_mask
for_each_node_mask() 函数用于遍历 NODEMASK 中所有置位的 node。参数 node 指向置位的位置,mask 参数指向遍历的 NODEMASK. 函数的实现根据 MAX_NUMNODES 而定,当 MAX_NUMNODES 大于 1,那么系统中存在多个 node,那么函数使用 for 循环,首先通过调用 first_node() 函数获得 NODEMASK 中第一个置位的 node,然后判断该 node 没有查过 MAX_NUMNODES, 那么函数执行遍历。遍历完一次之后,函数调用 next_node() 函数从当前 node 查找下一个置位 node,以此遍历 NODEMASK 中所有的置位 node.
如果 MAX_NUMNODES 等于 1,那么函数首先调用 nodes_empty() 判断 NODEMASK 是否为空,如果不为空,那么函数执行 1 次,且 node 为 0. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] for_each_node_mask --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: for_each_node_mask
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
int idx ;
/* Clear all */
nodes_clear ( node_a );
/* set special node */
node_set ( 12 , node_a );
node_set ( 16 , node_a );
/* iterator */
for_each_node_mask ( idx , node_a )
printk ( "Online-node: %d \n " , idx );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod for_each_node_mask-default.ko
for_each_node_mask_default: loading out-of-tree module taints kernel.
Online-node: 12
Online-node: 16
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
first_node
next_node
init_nodemask_of_node
init_nodemask_of_node() 函数用于初始化指定的 NODEMASK,并将指定的 node 置位。参数 node 指向需要置位的位置,参数 mask 指向 NODEMASK. 函数通过调用 nodes_clear() 函数将 NODEMASK 中所有的 node 清零,接着函数调用 node_set() 函数将 NODEMASK 指定的 node 置位. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_and --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: init_nodemask_of_node
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
int i ;
/* Initialize and set special node */
init_nodemask_of_node ( & node_a , 12 );
/* interate */
for_each_node_mask ( i , node_a )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod init_nodemask_of_node-default.ko
init_nodemask_of_node_default: loading out-of-tree module taints kernel.
Online-node: 12
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_clear
node_set
first_unset_node/__first_unset_node
first_unset_node/__first_unset_node 函数用于从指定的 NODEMASK 中找到第一个清零的 node。参数 mask 指向指定的 NODEMASK. 函数通过调用 find_first_zero_bit() 函数在 NODEMASK 中找到第一个清零的 bit,然后将找到的结果与 MAX_NUMNODES 进行比较,以此确认找到的 node 没有越界. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] first_unset_node --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask:first_unset_node
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
/* set all bits */
nodes_setall ( node_a );
/* clear special bits */
node_clear ( 12 , node_a );
/* first lowest clear bit */
printk ( "The first clear bit: %d \n " , first_unset_node ( node_a ));
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod first_unset_node-default.ko
first_unset_node_default: loading out-of-tree module taints kernel.
The first clear bit: 12
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
find_first_zero_bit
next_node_in/__next_node_in
next_node_in/__next_node_in 函数用于在 NODEMASK 中从指定 node 中开始查找第一个置位的 node,如果没有找到,那么函数继续从第一个 node 开始查找。参数 n 指明从指定的 node 位置,src 参数用于指向需要查找的 NODEMASK. 函数核心在 __next_node_in() 函数中实现,函数首先在 14 行通过调用 __next_node() 函数获得指定的置位位置,如果找到,则返回; 反之如果没有找到,那么函数调用 __first_node() 函数从头开始查找. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] next_node_in --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask:next_node_in
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
/* Clear all bits */
nodes_clear ( node_a );
/* Set special bits */
node_set ( 12 , node_a );
/* next lowest set bit */
printk ( "The next bit for 13th: %d \n " , next_node_in ( 13 , node_a ));
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod next_node_in-default.ko
next_node_in_default: loading out-of-tree module taints kernel.
The next bit for 13th: 12
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
__first_node
first_node
__next_node
next_node/__next_node
next_node/__next_node 函数用于在 NODEMASK 中获得从指定 node 之后第一个置位的 node,参数 n 指向开始查找的位置,src 指向查找的 NODEMASK. 函数通过调用 find_next_bit() 函数从 NDOEMASK 中的指定位置开始查找第一个置位的 node,然后将查找的结果与 MAX_NUMNODES 进行比较,以确保查找的结果没有越界。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] next_node --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask:next_node
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
/* Clear all bits */
nodes_clear ( node_a );
/* Set special bits */
node_set ( 12 , node_a );
node_set ( 16 , node_a );
node_set ( 17 , node_a );
/* next lowest set bit */
printk ( "The next bit for 13th: %d \n " , next_node ( 13 , node_a ));
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod next_node-default.ko
next_node_default: loading out-of-tree module taints kernel.
The next bit for 13th: 16
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
find_next_bit
first_node/__first_node
first_node/__first_node 函数用于获得 NODEMASK 从最低位开始第一个置位的 node。 参数 src 指向指定的 NODEMASK. 函数通过调用 find_first_bit() 函数实现查找逻辑,并在 MAX_NUMNODES 和找到的 node 中取最小值,确保查找不越界. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] first_node --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask:first_node
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
/* Clear all bits */
nodes_clear ( node_a );
/* Set special bits */
node_set ( 12 , node_a );
node_set ( 14 , node_a );
/* first lowest set bit */
printk ( "The first lowest set bit: %d \n " , first_node ( node_a ));
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod first_node-default.ko
first_node_default: loading out-of-tree module taints kernel.
The first lowest set bit: 12
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
find_first_bit
nodes_shift_left/__nodes_shift_left
nodes_shift_left/__nodes_shift_left 函数的作用是将指定的 NODEMASK 的所有 node 向左移动指定的位数,并将左移的结果存储在指定的 NODEMASK 中。参数 dst 用于存储左移之后的结果,src 参数用于指向需要左移的 NODEMASK,参数 n 指明需要左移的位数. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_shift_left --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_shift_left
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
/* Set special bits */
node_set ( 12 , node_a );
/* Shift left */
nodes_shift_left ( node_b , node_a , 2 );
/* iterate all node */
for_each_node_mask ( i , node_b )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_shift_left-default.ko
nodes_shift_left_default: loading out-of-tree module taints kernel.
Online-node: 14
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
bitmap_shift_left
nodes_shift_right/__node_shift_right
nodes_shift_right/__node_shift_right 函数用于将指定的 NODEMASK 中所有 node 右移指定的位数,并将结果存储在指定的 NODEMASK. 参数 dst 用于存储右移之后的结果,src 参数用于指向需要右移的 NODEMASK,参数 n 指明右移的位数. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_shift_right --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_shift_right
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
/* Set special bits */
node_set ( 12 , node_a );
/* Shift right */
nodes_shift_right ( node_b , node_a , 2 );
/* iterate all node */
for_each_node_mask ( i , node_b )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" )
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_shift_right-default.ko
nodes_shift_right_default: loading out-of-tree module taints kernel.
Online-node: 10
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
bitmap_shift_right
nodes_weight/__nodes_weight
nodes_weight/__nodes_weight 函数用于获得 NODEMASK 中置位 node 的数量。参数 nodemask 用于指向需要检测的 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_weight --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_weight
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
int weight ;
/* Clear all bits */
nodes_clear ( node_a );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 4 , node_a );
weight = nodes_weight ( node_a );
printk ( "NODE A weight %d \n " , weight );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_weight-default.ko
nodes_weight_default: loading out-of-tree module taints kernel.
NODE A weight 2
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_full/__nodes_full
nodes_full/__nodes_full 函数用于判断 NODEMASK 的所有 node 都已经置位,如果都置位,那么返回真,反之为假。参数 src 指向需要检测的 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_full --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_full
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_setall ( node_b );
/* Set special bits */
node_set ( 2 , node_a );
if ( nodes_full ( node_b ))
printk ( "Node b is full. \n " );
if ( ! nodes_full ( node_a ))
printk ( "Node a is not full. \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_full-default.ko
nodes_full_default: loading out-of-tree module taints kernel.
Node b is full.
Node a is not full.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_empty/__nodes_empty
nodes_empty/__nodes_empty 函数用于判断 NODEMASK 为空,即 NODEMASK 里面所有 node 都清零。参数 src 指向特定的 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_empty --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_empty
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
/* Set special bits */
node_set ( 2 , node_a );
if ( ! nodes_empty ( node_a ))
printk ( "NODEMASK A is not emtpy. \n " );
if ( nodes_empty ( node_b ))
printk ( "NODEMASK B is empty. \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_empty-default.ko
nodes_empty_default: loading out-of-tree module taints kernel.
NODEMASK A is not emtpy.
NODEMASK B is empty.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_subset/__nodes_subset
nodes_subset/__nodes_subset 函数用于判断两个 NODEMASK 之间存在子集关系。参数 src1 用于判断是否为参数 src2 的子集。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_subset --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_subset
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
nodemask_t node_c ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
nodes_clear ( node_c );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 4 , node_a );
node_set ( 2 , node_b );
node_set ( 1 , node_c );
if ( nodes_subset ( node_b , node_a ))
printk ( "B is subset of A. \n " );
if ( ! nodes_subset ( node_c , node_a ))
printk ( "C is not subset of A \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_subset-default.ko
nodes_subset_default: loading out-of-tree module taints kernel.
B is subset of A.
C is not subset of A
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_intersects/__nodes_intersects_
nodes_intersects/__nodes_intersects 函数用于判断两个 NODEMASK 之间是否存在交集,也就是是否用相同置位的 node。参数 src1 和 src2 分别指向对比的 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_intersects --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_intersects
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 4 , node_a );
node_set ( 2 , node_b );
if ( nodes_intersects ( node_a , node_b ))
printk ( "Intersect between a and b. \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_intersects-default.ko
nodes_intersects_default: loading out-of-tree module taints kernel.
Intersect between a and b.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_equal/__nodes_equal
nodes_equal/__nodes_equal 函数用于对比两个 NDOEMASK 是否相等,如果相等,则返回 true, 反之返回 false. 参数 src1 和 src2 用于指向对比的两个 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_equal --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_equal
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
nodemask_t node_c ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
nodes_clear ( node_c );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 4 , node_a );
node_set ( 2 , node_b );
node_set ( 2 , node_c );
if ( ! nodes_equal ( node_a , node_b ))
printk ( "node_a doesn't equal node_b \n " );
if ( nodes_equal ( node_b , node_c ))
printk ( "node_b equal node_c \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_equal-default.ko
nodes_equal_default: loading out-of-tree module taints kernel.
node_a doesn't equal node_b
node_b equal node_c
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_complement/__nodes_complement
nodes_complement/__nodes_complement 函数用于获得指定 NODEMASK 所有 node 取反值。参数 dst 用于存储取反之后的结果,src 用于取反的 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_complement --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_complement
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
/* Set special bits */
node_set ( 2 , node_a );
nodes_complement ( node_b , node_a );
/* Iterate set bits */
for_each_node_mask ( i , node_b )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_complement-default.ko
nodes_complement_default: loading out-of-tree module taints kernel.
Online-node: 0
Online-node: 1
Online-node: 3
Online-node: 4
Online-node: 5
Online-node: 6
Online-node: 7
Online-node: 8
Online-node: 9
Online-node: 10
Online-node: 11
Online-node: 12
Online-node: 13
Online-node: 14
Online-node: 15
Online-node: 16
Online-node: 17
Online-node: 18
Online-node: 19
Online-node: 20
Online-node: 21
Online-node: 22
Online-node: 23
Online-node: 24
Online-node: 25
Online-node: 26
Online-node: 27
Online-node: 28
Online-node: 29
Online-node: 30
Online-node: 31
Online-node: 32
Online-node: 33
Online-node: 34
Online-node: 35
Online-node: 36
Online-node: 37
Online-node: 38
Online-node: 39
Online-node: 40
Online-node: 41
Online-node: 42
Online-node: 43
Online-node: 44
Online-node: 45
Online-node: 46
Online-node: 47
Online-node: 48
Online-node: 49
Online-node: 50
Online-node: 51
Online-node: 52
Online-node: 53
Online-node: 54
Online-node: 55
Online-node: 56
Online-node: 57
Online-node: 58
Online-node: 59
Online-node: 60
Online-node: 61
Online-node: 62
Online-node: 63
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_andnot/__nodes_andnot
nodes_andnot/__nodes_andnot 函数的作用是将一个 NODEMASK 与另外一个 NODEMASK 所有 node 取反之后的值相与,并将结果存储在指定的 NODEMASK。参数 dst 用于存储结果的 NODEMASK, 参数 src1 指定第一个 NODEMASK, 参数 src2 指定第二个用于取反操作的 NODEMASK,函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_andnot --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_andnot
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
nodemask_t node_c ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 3 , node_b );
/* NODEMASK intersection */
nodes_andnot ( node_c , node_a , node_b );
/* Iterate set bits */
for_each_node_mask ( i , node_c )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_andnot-default.ko
nodes_andnot_default: loading out-of-tree module taints kernel.
Online-node: 2
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_xor/__nodes_xor
nodes_xor/__nodes_xor 函数用于将两个 NODEMASK 的每个 node 异或的结果存储在指定的 NODEMASK 中。参数 dst 用于存储结果的 NODEMASK, 参数 src1 和 src2 指定参与异或的 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_xor --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_xor
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
nodemask_t node_c ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 3 , node_b );
/* NODEMASK intersection */
nodes_xor ( node_c , node_a , node_b );
/* Iterate set bits */
for_each_node_mask ( i , node_c )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_xor-default.ko
nodes_xor_default: loading out-of-tree module taints kernel.
Online-node: 2
Online-node: 3
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_or/__nodes_or
nodes_or/__nodes_or 函数用于将两个 NODEMASK 的每个 node 相或的结果存储在指定的 NODEMASK 中。参数 dst 指向存储结果的 NODEMASK,参数 src1 和 src2 指向相与的两个 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_or --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_or
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
nodemask_t node_c ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 3 , node_b );
/* NODEMASK intersection */
nodes_or ( node_c , node_a , node_b );
/* Iterate set bits */
for_each_node_mask ( i , node_c )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_or-default.ko
nodes_or_default: loading out-of-tree module taints kernel.
Online-node: 2
Online-node: 3
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_and/__nodes_and
nodes_and/__nodes_and 函数的作用是将两个 NODEMASK 相与之后的结果存储在指定的 NODEMASK. 该操作会将 NODEMASK 中每个 node 进行与操作。参数 dst 指向存储结果的 NODEMASK, 参数 src1 和 src2 为相与的两个 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_set --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_and
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node_a ;
nodemask_t node_b ;
nodemask_t node_c ;
int i ;
/* Clear all bits */
nodes_clear ( node_a );
nodes_clear ( node_b );
/* Set special bits */
node_set ( 2 , node_a );
node_set ( 3 , node_a );
node_set ( 2 , node_b );
/* NODEMASK intersection */
nodes_and ( node_c , node_a , node_b );
/* Iterate set bits */
for_each_node_mask ( i , node_c )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_and-default.ko
nodes_and_default: loading out-of-tree module taints kernel.
Online-node: 2
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
node_test_and_set/__node_test_and_set
node_test_and_set/__node_test_and_set 函数用于检测 NODEMASK 指定 NODE 是否置位,如果是返回 true,反之返回 false,并且将指定的 NODE 置位。参数 node 只用指定需要检测的 NODE, 参数 nodemask 指向指定的 NODEMASK. 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_set --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_test_and_set
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node ;
/* Clear all bits */
nodes_clear ( node );
if ( ! node_test_and_set ( 2 , node ))
printk ( "NODE 2 is clear. \n " );
if ( node_isset ( 2 , node ))
printk ( "NODE 2 is set. \n " );
if ( node_test_and_set ( 2 , node ))
printk ( "NODE 2 has set. \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/ lib / modules / 5 . 0 . 0 / extra # insmod node_test_and_set - default . ko
node_test_and_set_default : loading out - of - tree module taints kernel .
NODE 2 is clear .
NODE 2 is set .
NODE 2 has set .
Hello modules on BiscuitOS
node_isset
node_isset() 函数用于检测 NODEMASK 中指定 NODE 是否置位,如果置位返回 true,反之返回 false. 参数 node 只用指定需要检测的 NODE, 参数 nodemask 指向指定的 NODEMASK, 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_isset --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_isset
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node ;
/* Clear all bits */
nodes_clear ( node );
/* Set special bits */
node_set ( 2 , node );
if ( node_isset ( 2 , node ))
printk ( "Node 2 is set. \n " );
if ( ! node_isset ( 3 , node ))
printk ( "Node 3 is clear. \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_isset-default.ko
node_isset_default: loading out-of-tree module taints kernel.
Node 2 is set.
Node 3 is clear.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_clear/__nodes_clear
nodes_clear()/__nodes_clear() 函数用于将 NODEMASK 中的所有 node 全部清零. 参数 nodemask 指向指定的 NODEMASK 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_clear --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_clear
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node ;
int i ;
/* Clear all bits */
nodes_clear ( node );
if ( ! node_test_and_set ( 2 , node ))
printk ( "Node 2 is clear. \n " );
if ( node_test_and_set ( 2 , node ))
printk ( "Node 2 is set before. \n " );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_clear-default.ko
nodes_clear_default: loading out-of-tree module taints kernel.
Node 2 is clear.
Node 2 is set before.
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
nodes_setall/__nodes_setall
nodes_setall()/__nodes_setall() 函数用于将 NODEMASK 中所有 node 都置位. 参数 nodemask 指向指定的 NODEMASK 函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] nodes_setall --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: nodes_setall
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node ;
int i ;
/* set all bits */
nodes_setall ( node );
/* Clear special bits */
node_clear ( 2 , node );
/* Iterate set bits */
for_each_node_mask ( i , node )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod nodes_setall-default.ko
nodes_setall_default: loading out-of-tree module taints kernel.
Online-node: 0
Online-node: 1
Online-node: 3
Online-node: 4
Online-node: 5
Online-node: 6
Online-node: 7
Online-node: 8
Online-node: 9
Online-node: 10
Online-node: 11
Online-node: 12
Online-node: 13
Online-node: 14
Online-node: 15
Online-node: 16
Online-node: 17
Online-node: 18
Online-node: 19
Online-node: 20
Online-node: 21
Online-node: 22
Online-node: 23
Online-node: 24
Online-node: 25
Online-node: 26
Online-node: 27
Online-node: 28
Online-node: 29
Online-node: 30
Online-node: 31
Online-node: 32
Online-node: 33
Online-node: 34
Online-node: 35
Online-node: 36
Online-node: 37
Online-node: 38
Online-node: 39
Online-node: 40
Online-node: 41
Online-node: 42
Online-node: 43
Online-node: 44
Online-node: 45
Online-node: 46
Online-node: 47
Online-node: 48
Online-node: 49
Online-node: 50
Online-node: 51
Online-node: 52
Online-node: 53
Online-node: 54
Online-node: 55
Online-node: 56
Online-node: 57
Online-node: 58
Online-node: 59
Online-node: 60
Online-node: 61
Online-node: 62
Online-node: 63
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
node_clear/__node_clear
node_clear()/__node_clear() 函数用于将指定的 NODEMASK 指定 NODE 清零。参数 node 只用指定 NODE, 参数 nodemask 指向指定的 NODEMASK。函数在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_clear --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_clear
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node ;
int i ;
/* Clear all bits */
nodes_clear ( node );
/* Set special bits */
node_set ( 2 , node );
/* Iterate set bits */
for_each_node_mask ( i , node )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_clear-default.ko
node_clear_default: loading out-of-tree module taints kernel.
Online-node: 2
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
node_set/__node_set
node_set() 函数用于置位 NODEMASK 指定 node. 参数 node 指向需要设置的 NODE ID,参数 dst 指向 NODEMASK. 在函数中,dstp 包含一个 bitmap,函数调用 set_bit() 函数设置了该 bitmap 的指定 bit。node_set() 在 BiscuitOS 的使用如下:
cd BiscuitOS
make menuconfig
[ * ] Package --- >
[ * ] nodemask --- >
[ * ] node_set --- >
开发者可以参考文档进行使用:
独立内核模块代码 – 独立程序开发办法
测试代码
/*
* Nodemask: node_set
*
* (C) 2021.01.10 BuddyZhang1 <buddy.zhang@aliyun.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* Module initialize entry */
static int __init BiscuitOS_init ( void )
{
nodemask_t node ;
int i ;
/* Clear all bits */
nodes_clear ( node );
/* Set special bits */
node_set ( 2 , node );
/* Iterate set bits */
for_each_node_mask ( i , node )
printk ( "Online-node: %d \n " , i );
printk ( "Hello modules on BiscuitOS \n " );
return 0 ;
}
/* Module exit entry */
static void __exit BiscuitOS_exit ( void )
{
}
module_init ( BiscuitOS_init );
module_exit ( BiscuitOS_exit );
MODULE_LICENSE ( "GPL" );
MODULE_AUTHOR ( "BiscuitOS <buddy.zhang@aliyun.com>" );
MODULE_DESCRIPTION ( "Common Device driver on BiscuitOS" );
BiscuitOS 运行结果
/lib/modules/5.0.0/extra # insmod node_set-default.ko
node_set_default: loading out-of-tree module taints kernel.
Online-node: 2
Hello modules on BiscuitOS
/lib/modules/5.0.0/extra #
附录
BiscuitOS Home
BiscuitOS Blog 2.0
Linux Kernel
Bootlin: Elixir Cross Referencer
捐赠一下吧 🙂