Questions tagged «linux-kernel»

该标签用于询问有关Linux内核本身内部的问题,尤其是有关编写在内核上下文中运行的代码(例如内核模块或驱动程序)的问题。有关在Linux中编写用户空间代码的问题,通常应标记为[linux]。由于Linux内核的内部结构不断变化,因此包含您感兴趣的精确内核版本会很有帮助。


3
在新的Linux内核中,上下文切换要慢得多
我们希望将服务器上的操作系统从Ubuntu 10.04 LTS升级到Ubuntu 12.04 LTS。不幸的是,运行已变为可运行线程的等待时间似乎从2.6内核大大增加到3.2内核。实际上,我们难以置信的延迟数字。 让我更具体地介绍一下测试。我们有一个运行两个线程的程序。第一个线程获取当前时间(使用RDTSC进行滴答),然后每秒发送一次条件变量信号。第二个线程等待条件变量,并在发出信号时唤醒。然后,它获取当前时间(使用RDTSC进行滴答)。计算第二个线程中的时间和第一个线程中的时间之间的时差,并将其显示在控制台上。此后,第二个线程再次等待条件变量。大约经过一秒钟后,第一个线程将再次发出信号。 因此,简而言之,我们每秒通过条件变量等待时间测量获得线程到线程的通信。 在内核2.6.32中,此延迟约为2.8-3.5 us,这是合理的。在内核3.2.0中,此延迟已增加到40-100 us左右。我排除了两台主机之间的硬件差异。它们在相同的硬件上运行(双插槽X5687 {Westmere-EP}处理器以3.6 GHz运行,具有超线程,speedstep和所有C状态均已关闭)。测试应用程序更改了线程的亲和力,以便在同一套接字的独立物理内核上运行它们(即,第一个线程在Core 0上运行,第二个线程在Core 1上运行),因此在该线程上不会发生线程跳动核心或套接字之间的跳动/通信。 这两台主机之间的唯一区别是,一台主机运行的内核版本为2.6.32-28(快速上下文切换框),而另一台则运行最新的Ubuntu 12.04 LTS内核为3.2.0-23版本(慢上下文)。开关盒)。所有BIOS设置和硬件均相同。 内核中是否有任何变化可以解释线程调度运行需要多长时间的可笑速度减慢? 更新: 如果您想在您的主机和Linux构建上运行测试,我已将代码发布到pastebin供您阅读。编译: g++ -O3 -o test_latency test_latency.cpp -lpthread 运行(假设您至少有一个双核计算机): ./test_latency 0 1 # Thread 1 on Core 0 and Thread 2 on Core 1 更新2:在大量搜索内核参数,发布有关内核更改和个人研究的文章之后,我已经弄清了问题所在,并发布了解决方案作为对此问题的解答。

2
在Linux内核模块中读取/写入文件
我知道所有关于为什么不应该从内核读取/写入文件,而是如何使用/ proc或netlink来执行此操作的讨论。我还是想读/写。我还阅读了《 驾驶我的坚果》-内核中不应该做的事情。 但是,问题在于2.6.30无法导出sys_read()。相反,它被包裹在SYSCALL_DEFINE3。因此,如果我在模块中使用它,则会收到以下警告: WARNING: "sys_read" [xxx.ko] undefined! WARNING: "sys_open" [xxx.ko] undefined! 显然insmod无法加载模块,因为链接未正确进行。 问题: 2.6.22之后如何在内核中读取/写入(其中sys_read()/ sys_open()不导出)? 通常,如何使用SYSCALL_DEFINEn()内核中包装在宏中的系统调用?

3
如果线程共享相同的PID,则如何识别它们?
我有一个与Linux中线程实现有关的查询。 Linux没有显式线程支持。在用户空间中,我们可能使用线程库(例如NPTL)来创建线程。现在,如果我们使用NPTL,则它支持1:1映射。 内核将使用该clone()函数来实现线程。 假设我创建了4个线程。那么就意味着: 将有4个task_struct。 在内部task_struct,将根据克隆参数提供共享资源(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)。 现在,我有以下查询: 4个线程的PID是否相同?如果有人可以详细说明,则如何共享PID。 如何识别不同的线程;有一些TID(线程ID)概念吗?

6
如何避免来自mongodb的transparent_hugepage / defrag警告?
我收到mongodb关于THP的以下警告 2015-03-06T21:01:15.526-0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2015-03-06T21:01:15.526-0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 但是我确实设法手动关闭了THP frederick@UbuntuVirtual:~$ cat /sys/kernel/mm/transparent_hugepage/enabled always madvise [never] frederick@UbuntuVirtual:~$ cat /sys/kernel/mm/transparent_hugepage/defrag always madvise [never] 我加入的伎俩transparent_hugepage=never,以GRUB_CMDLINE_LINUX_DEFAULT中/etc/default/grub和添加 if test -f /sys/kernel/mm/transparent_hugepage/defrag; then echo never > /sys/kernel/mm/transparent_hugepage/defrag fi 至 /etc/rc.local 我到底该如何避免警告?


2
什么是vdso和vsyscall?
我做了 sudo cat /proc/1/maps -vv 我试图弄清楚输出,可以看到很多共享库都按预期映射到了内存映射段。 7f3c00137000-7f3c00179000 r-xp 00000000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8 7f3c00179000-7f3c00379000 ---p 00042000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8 7f3c00379000-7f3c0037a000 r--p 00042000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8 7f3c0037a000-7f3c0037b000 rw-p 00043000 08:01 21233923 /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8 7f3c0037b000-7f3c00383000 r-xp 00000000 08:01 21237216 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0 7f3c00383000-7f3c00583000 ---p 00008000 08:01 21237216 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0 7f3c00583000-7f3c00584000 r--p 00008000 08:01 21237216 /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0 7f3c00584000-7f3c00585000 rw-p …
89 c  linux  linux-kernel  kernel  vdso 

3
使用gdb在指定的可执行文件之外单步执行汇编代码会导致错误“找不到当前函数的边界”
我不在gdb的目标可执行文件之外,甚至没有对应于该目标的堆栈。无论如何,我都想单步执行,以便我可以验证汇编代码中发生的事情,因为我不是x86汇编方面的专家。不幸的是,gdb拒绝执行此简单的程序集级调试。它允许我在适当的断点处设置和停止,但是一旦我尝试单步执行,gdb就会报告错误“找不到当前函数的边界”,并且EIP不会更改。 额外细节: 机器代码是由gcc asm语句生成的,我从objdump -d的输出将其复制到了正在执行的内核内存位置。我不介意使用加载程序将目标代码加载到重定位地址的简单方法,但是请记住,加载必须在内核模块中完成。 我想另一种选择是产生一个伪造的内核模块或调试信息文件以提供给gdb,使它相信该区域在程序代码内。gdb在内核可执行文件本身上运行良好。 (对于那些真正想知道的人,我是在运行时将代码插入VMware VM内的Linux内核数据空间中,然后通过gdb调试它,通过VMware Workstation的内置gdb存根对内核进行远程调试。注意,我不是在编写内核漏洞利用;我是写原型的安全研究生。) (我可以在程序集中的每条指令上设置一个断点。这可以工作,但是一段时间后会变得很费力,因为x86汇编指令的大小各不相同,并且每次重新启动时程序集的位置都会改变。)

2
在Linux内核中使用浮点
我正在阅读Robert Love的“ Linux内核开发”,并且遇到了以下段落: 无需(轻松)使用浮点数 当用户空间进程使用浮点指令时,内核将管理从整数到浮点模式的转换。内核在使用浮点指令时必须执行的操作因体系结构而异,但是内核通常会捕获陷阱,然后启动从整数模式到浮点模式的转换。 与用户空间不同,内核没有对浮点的无缝支持的奢侈之处,因为它无法轻易地陷入陷阱。在内核内部使用浮点数需要手动保存和恢复浮点数寄存器,以及其他可能的琐事。简短的答案是:不要这样做!除了极少数情况,内核中没有浮点运算。 我从未听说过这些“整数”和“浮点”模式。它们到底是什么?为什么需要它们?这种区别是否存在于主流硬件体系结构(例如x86)上,还是特定于某些更特殊的环境?从进程和内核的角度来看,从整数模式到浮点模式的转换到底需要什么?

1
图像vs zImage vs uImage
它们之间有什么区别? 我知道u-boot需要uImage格式的内核。 我首先使用从第1阶段加载程序引导的系统,然后调用u-boot。我想放弃u-boot并直接从第1阶段加载程序启动。我必须使用哪种类型的内核映像?

5
选择Linux I / O调度程序
我读到,据说可以通过写入/ sys / block / [disk] / queue / scheduler来更改正在运行的内核上特定设备的I / O调度程序。例如,我可以在系统上看到: anon@anon:~$ cat /sys/block/sda/queue/scheduler noop anticipatory deadline [cfq] 默认值是完全公平的队列调度程序。我想知道的是,在自定义内核中包括所有四个调度程序是否有任何用处。除非内核足够聪明地为正确的硬件选择正确的调度程序,特别是基于闪存的驱动器的“ noop”调度程序,以及针对传统驱动器的其他调度程序,否则编译一个以上的调度程序似乎没有多大意义。硬盘。 是这样吗

7
了解Linux内核中的container_of宏
当我浏览Linux内核时,我发现了一个container_of定义如下的宏: #define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );}) 我了解container_of的作用,但我不明白的是最后一句话,即 (type *)( (char *)__mptr - offsetof(type,member) );}) 如果我们按如下方式使用宏: container_of(dev, struct wifi_device, dev); 最后一句话的相应部分是: (struct wifi_device *)( (char *)__mptr - offset(struct wifi_device, dev); 看起来什么也没做。有人可以在这里填补空白吗?


2
如何识别Linux块设备的请求队列
我正在研究通过网络连接硬盘的驱动程序。有一个错误,如果我在计算机上启用了两个或多个硬盘,则只有第一个硬盘可以查看并识别分区。结果是,如果我在hda上有1个分区,而在hdb上有1个分区,那么当我连接hda时,就会有一个可以挂载的分区。因此,hda1在挂载后立即获得blkid xyz123。但是当我继续安装hdb1时,它也出现了相同的blkid,实际上,驱动程序是从hda而不是hdb读取的。 所以我想我找到了司机搞砸的地方。下面是一个调试输出,包括一个dump_stack,我将其放在第一个似乎访问错误设备的位置。 这是代码部分: /*basically, this is just the request_queue processor. In the log output that follows, the second device, (hdb) has just been connected, right after hda was connected and hda1 was mounted to the system. */ void nblk_request_proc(struct request_queue *q) { struct request *req; ndas_error_t err = NDAS_OK; …

2
Linux reboot()系统调用的幻数
Linux编程接口在第3章中将进行如下练习: 当使用特定于Linux的reboot()系统调用来重新引导系统时,必须将第二个参数magic2指定为一组幻数(例如LINUX_REBOOT_MAGIC2)之一。这些数字的意义是什么?(将它们转换为十六进制提供了一个线索。) 手册页告诉我们magic2可以是LINUX_REBOOT_MAGIC2(672274793),LINUX_REBOOT_MAGIC2A(85072278),LINUX_REBOOT_MAGIC2B(369367448)或LINUX_REBOOT_MAGIC2C(537993216)之一。我无法用十六进制解释它们的含义。我还查看了/usr/include/linux/reboot.h,也没有给出任何有用的评论。 然后,我在内核的源代码中搜索sys_reboot的定义。我发现的只是一个头文件中的声明。 因此,我的第一个问题是,这些数字的意义是什么?我的第二个问题是sys_reboot的定义在哪里,以及如何找到它的? 编辑:我在中找到了定义kernel/sys.c。我只为rep sys_reboot,而忘记了magic编号的grep。我认为定义必须隐藏在一些宏技巧的后面,因此我查看了下面的System.map文件/boot,并在旁边找到了该文件ctrl_alt_del。然后我为该符号摸索了一下,这使我找到了正确的文件。如果我是从源代码编译内核的,则可以尝试找到定义该符号的目标文件,然后从那里去。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.