我编写了一个程序,如果网络接口发生了变化,需要得到通知,特别是新的一个出现或者已经存在.我的研究带来了netlink及其RTMGRP_LINK信号.这个手册页给出了一个我尚不清楚的例子.
它有这个代码:
memset(&sa, 0, sizeof(sa));
snl.nl_family = AF_NETLINK;
snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
bind(fd, (struct sockaddr*)&sa, sizeof(sa));
Run Code Online (Sandbox Code Playgroud)
我的理解是这是一个初始化部分,用于启用某些信号.我想必须有一个处理事件的处理程序子程序.
我的问题是:
这是启用该事件的正确代码段吗?
如何处理事件:我需要一些处理程序吗?
包含相关信息(关于网络接口及其更改)的数据结构是什么?
谢谢你的帮助.
很偶然地在内核丛林中偶然发现了一些代码并且有点困惑。有两种实现kzalloc():在tools/virtio/linux/kernel.h 中,主要的在linux/slab.h 中。显然,在大多数情况下,使用第二个。但有时使用“virtio” kzalloc()。
“virtio”kzalloc()看起来像这样:
static inline void *kzalloc(size_t s, gfp_t gfp)
{
void *p = kmalloc(s, gfp);
memset(p, 0, s);
return p;
}
Run Code Online (Sandbox Code Playgroud)
我的困惑是kmalloc()在“tools”目录中使用的“fake”会返回 NULL 指针。此外,该memset()实现似乎不检查 NULL 指针,因此可能存在 NULL 指针取消引用。这是一个错误还是我错过了什么?
我目前正在尝试调试在以太网上运行的ATM封装层.基本上ATM信元在以太网报头之后按顺序存储.但是我怀疑司机天真接近sk_buffs的方法被打破了.
驱动程序盲目地假设skb-> data可以迭代但查看virtio_net.c的内核代码:page_to_skb我看到以下行为:
memcpy(hdr, p, hdr_len);
len -= hdr_len;
p += offset;
copy = len;
if (copy > skb_tailroom(skb))
copy = skb_tailroom(skb);
memcpy(skb_put(skb, copy), p, copy);
Run Code Online (Sandbox Code Playgroud)
然后进一步说:
while (len) {
set_skb_frag(skb, page, offset, &len);
page = (struct page *)page->private;
offset = 0;
}
Run Code Online (Sandbox Code Playgroud)
这似乎表明缓冲区是碎片化的,只有第一部分可以直接从skb-> data访问.
我应该用什么来获取基础数据.理想情况下,我希望在memcpy将块存入我维护的重组缓冲区之前,将任意偏移量的几个字节查看到以太网数据包中.我该怎么用呢?
我是一名从事 Linux 进程研究的学生,我需要更多地了解它们才能继续我的实验。在网上阅读几本书和一些东西时,我遇到了task_struct,我不确定我是否完全理解,并希望确认/纠正我现有的想法。
从我认为我已经理解的task_struct是,作为进程描述符的 C 结构包含内核可能需要了解的关于进程的所有信息。在进程内核堆栈的末尾有另一个结构体thread_info,它有一个指向进程的指针task_struct。
另一个问题:如何访问task_struct进程的 ?是否有计算来找到它的位置thread_info?内核中有宏/函数吗?
我们知道 Linux 内核是用 C 编写的。但它是否也调用了标准 C 函数,malloc()或者像mmap()GNU C 库(glibc)提供的额外函数?在那种情况下,这很奇怪,因为与硬件的直接低级交互,例如内存管理,应该几乎总是内核的任务。那么,哪个依赖于另一个?哪个更基本/低级?
我有一些内核模块可以打印到日志中
printk(KERN_INFO "Something\n");
Run Code Online (Sandbox Code Playgroud)
加载模块时,我发现时间dmesg超过了当前时间date:
-bash-4.4$ dmesg -T | grep some_driver
[Sat May 16 22:25:03 2020] some_driver: Something
-bash-4.4$ date
Sat May 16 22:22:02 UTC 2020
Run Code Online (Sandbox Code Playgroud)
可能是什么原因?
PS Linux 内核版本是 4.4,它位于 VMware vSphere VM 中。
我一直在阅读有关Linux上的TCP实现一些文章,我糊涂了,之间有什么区别net.ipv4.tcp_max_syn_backlog,并net.core.somaxconn与backlog作为参数传递给listen()系统调用,什么是它们之间的关系。
PS 我想解释内核 4.15,因为我发现在这个主题上,旧内核和新内核之间存在一些差异。
我的 Linux 有 6 个 CPU 核心,其中一个(第 0 个)通过 grub 配置文件(/etc/default/grub)与 Linux 调度程序隔离,扩展名为GRUB_CMDLINE_LINUX_DEFAULT="quiet isolcpus=0 nohz_full=1".
我检查了隔离情况cat /sys/devices/system/cpu/isolated,没问题。
以下是完整的代码片段(使用 编译gcc -pthread ...):
#define _GNU_SOURCE
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
void *thread(void *ptr)
{
for(;;) {
show_curr_cpu("pthread");
sleep(2);
}
}
void show_curr_cpu(char *str)
{
unsigned int cpu, node;
if (getcpu(&cpu, &node) != 0) {
perror("getcpu");
return;
}
printf("[%s]Current CPU: %u\n", str, cpu);
}
int main(void)
{
show_curr_cpu("main-bfr");
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset); /* …Run Code Online (Sandbox Code Playgroud) 我get_user_pages在 Linux 内核驱动程序中使用来固定内存以用于 [硬件] DMA。一切似乎都很好 - 但我很难证明“固定”正在做正确的事情。
当我在做完之后检查物理页面上的标志时get_user_pages- 页面不会出现“锁定”(正如人们可能认为的那样)。事实上,我认为其他“活动”页面的标志与我通过get_user_pages.
我看到的唯一区别是 get_user_pages在页面上进行了引用计数。所以我想我的问题是 -单独持有这个引用是否足以保证这个页面永远不会被换出、移动,或者我的用户空间的 vaddr 仍然/总是引用相同的底层页面?
我能找到的所有驱动程序源似乎都使用这种机制,文档似乎表明这是正确的方法 - 但我很难“证明”这会给我正确、可靠、预期的行为。
我正在尝试完全消除安静机器上一组内核上的计时器中断。这些是这些内核定期处理的唯一中断。我已经isolcpu对它们进行了处理,并使用 构建了一个内核CONFIG_NO_HZ_FULL,实际上现在它们大约每秒只接收一次计时器中断。是否可以删除这个残留的 1Hz 定时器中断?
该内核文档建议在某些时候偶尔需要进行勾选:
一些进程处理操作仍然需要偶尔的调度时钟滴答。这些操作包括计算CPU负载、维护sched平均值、计算CFS实体vruntime、计算avenrun以及进行负载均衡。目前,它们是通过每秒左右的调度时钟滴答来容纳的。正在进行的工作将消除对这些不频繁的调度时钟滴答的需要。
这个内核补丁“删除 1 Hz 滴答代码”表明它在更高版本的内核中已被删除:
现在 1Hz 滴答已卸载到工作队列,我们可以安全地删除用于在本地处理它的残留代码。
我构建了 5.3.0 内核,希望能够删除这个残留的刻度线,但它仍然存在。
我还需要设置其他启动参数吗?最新版本的内核中是否真的删除了剩余计时器滴答声?(这个问题有一些相关信息)