栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用Cpuset将内核模块隔离到特定的内核

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Cpuset将内核模块隔离到特定的内核

因此,我希望模块在隔离的内核中执行。

实际上隔离了我们系统中的特定核心并仅对该核心执行一个特定过程

这是一个有效的源代码,使用内核3.16在Debian机器上进行了编译和测试。我将描述如何首先加载和卸载以及传递的参数的含义。

所有资源都可以在github上找到…

https://github.com/harryjackson/doc/tree/master/linux/kernel/toy/toy

构建并加载模块…

makeinsmod toy param_cpu_id=2

卸载模块使用

rmmod toy

我没有使用modprobe,因为它需要一些配置等。我们传递给

toy
内核模块的参数是我们要隔离的CPU。除非被调用的设备操作正在该CPU上执行,否则它们将不会运行。

加载模块后,您可以在此处找到它

/dev/toy

简单的操作,例如

cat /dev/toy

创建内核模块捕获的事件并产生一些输出。您可以使用查看输出

dmesg

源代码…

#include <linux/module.h>#include <linux/fs.h>#include <linux/miscdevice.h>MODULE_LICENSE("GPL");MODULE_AUTHOR("Harry");MODULE_DEscriptION("toy kernel module");MODULE_VERSION("0.1"); #define  DEVICE_NAME "toy"#define  CLASS_NAME  "toy"static int    param_cpu_id;module_param(param_cpu_id    , int, (S_IRUSR | S_IRGRP | S_IROTH));MODULE_PARM_DESC(param_cpu_id, "CPU ID that operations run on");//static void    bar(void *arg);//static void    foo(void *cpu);static int     toy_open(   struct inode *inodep, struct file *fp);static ssize_t toy_read(   struct file *fp     , char *buffer, size_t len, loff_t * offset);static ssize_t toy_write(  struct file *fp     , const char *buffer, size_t len, loff_t *);static int     toy_release(struct inode *inodep, struct file *fp);static struct file_operations toy_fops = {  .owner = THIS_MODULE,  .open = toy_open,  .read = toy_read,  .write = toy_write,  .release = toy_release,};static struct miscdevice toy_device = {  .minor = MISC_DYNAMIC_MINOR,  .name = "toy",  .fops = &toy_fops};//static int CPU_IDS[64] = {0};static int toy_open(struct inode *inodep, struct file *filep) {  int this_cpu = get_cpu();  printk(KERN_INFO "open: called on CPU:%dn", this_cpu);  if(this_cpu == param_cpu_id) {    printk(KERN_INFO "open: is on requested CPU: %dn", smp_processor_id());  }  else {    printk(KERN_INFO "open: not on requested CPU:%dn", smp_processor_id());  }  put_cpu();  return 0;}static ssize_t toy_read(struct file *filep, char *buffer, size_t len, loff_t *offset){  int this_cpu = get_cpu();  printk(KERN_INFO "read: called on CPU:%dn", this_cpu);  if(this_cpu == param_cpu_id) {    printk(KERN_INFO "read: is on requested CPU: %dn", smp_processor_id());  }  else {    printk(KERN_INFO "read: not on requested CPU:%dn", smp_processor_id());  }  put_cpu();  return 0;}static ssize_t toy_write(struct file *filep, const char *buffer, size_t len, loff_t *offset){  int this_cpu = get_cpu();  printk(KERN_INFO "write called on CPU:%dn", this_cpu);  if(this_cpu == param_cpu_id) {    printk(KERN_INFO "write: is on requested CPU: %dn", smp_processor_id());  }  else {    printk(KERN_INFO "write: not on requested CPU:%dn", smp_processor_id());  }  put_cpu();  return 0;}static int toy_release(struct inode *inodep, struct file *filep){  int this_cpu = get_cpu();  printk(KERN_INFO "release called on CPU:%dn", this_cpu);  if(this_cpu == param_cpu_id) {    printk(KERN_INFO "release: is on requested CPU: %dn", smp_processor_id());  }  else {    printk(KERN_INFO "release: not on requested CPU:%dn", smp_processor_id());  }  put_cpu();  return 0;}static int __init toy_init(void) {  int cpu_id;  if(param_cpu_id < 0 || param_cpu_id > 4) {    printk(KERN_INFO "toy: unable to load module without cpu parametern");    return -1;  }  printk(KERN_INFO "toy: loading to device driver, param_cpu_id: %dn", param_cpu_id);  //preempt_disable(); // See notes below  cpu_id = get_cpu();  printk(KERN_INFO "toy init called and running on CPU: %dn", cpu_id);  misc_register(&toy_device);  //preempt_enable(); // See notes below  put_cpu();  //smp_call_function_single(1,foo,(void *)(uintptr_t) 1,1);  return 0;}static void __exit toy_exit(void) {    misc_deregister(&toy_device);    printk(KERN_INFO "toy exit calledn");}module_init(toy_init);module_exit(toy_exit);

上面的代码包含您要求的两种方法,即隔离CPU和在

init
隔离的内核上运行。

初始化时

get_cpu
会禁用抢占,即之后发生的任何事情都不会被内核抢占,而是会在一个内核上运行。请注意,这是使用3.16内核完成的,根据您的内核版本,您的工作量可能会有所不同,但我认为这些API已经存在了很长时间

这是Makefile …

obj-m += toy.oall:    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modulesclean:    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

笔记。

get_cpu
被声明
linux/smp.h

#define get_cpu()   ({ preempt_disable(); smp_processor_id(); })#define put_cpu()   preempt_enable()

因此您实际上不需要在致电

preempt_disable
之前致电
get_cpu
。get_cpu调用是以下调用序列的包装。

preempt_count_inc();barrier();

而put_cpu实际上就是这样做的…

barrier();if (unlikely(preempt_count_dec_and_test())) {  __preempt_schedule();}

使用上面的方法,您可以任意选择。几乎所有这些都来自以下来源。

Google for … smp_call_function_single

Linux内核开发,Robert Love着书。

http://derekmolloy.ie/writing-a-linux-kernel-module-part-2-a-character-
device/

https://github.com/vsinitsyn/reverse/blob/master/reverse.c



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/412417.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号