linux-sides-Timers and time management-Introduction

这篇文章 Timers and time management in the Linux kernel. Part 1. 是出自 linux-insides一书中 Timers and time management 章节 Introduction 内核版本比对5.3-rc 进行了相关调整, 增加相关备注 Linux内核中的定时器和时间管理. Part 1. 介绍 这是另一篇文章,它在linux-insides一书中开启了新的篇章。前面的部分描述了系统调用概念,现在是时候开始新篇章了。正如人们可能从标题中理解的那样,本章将专门讨论Linux内核中的“定时器”和“时间管理”。当前章节的主题选择并非偶然。定时器(通常是时间管理)非常重要,并且在Linux内核中广泛使用。 Linux内核使用计时器执行各种任务,例如TCP实现中的不同超时,内核知道当前时间,调度异步函数,下一个事件中断调度和还有更多。 因此,我们将开始学习本部分中不同时间管理相关内容的实现。我们将看到不同类型的计时器以及不同的Linux内核子系统如何使用它们。与往常一样,我们将从Linux内核的最早部分开始,并完成Linux内核的初始化过程。我们已经在特殊的章节-Kernel initialization process中完成了它,它描述了Linux内核的初始化过程,但是你可能还记得我们错过了那里有些东西。其中一个是定时器的初始化。 我们开始吧。 初始化非标准PC硬件时钟 Linux内核解压缩后(更多关于此内容,您可以在内核解压缩部分中阅读)非特定代码开始在init/main.c源代码文件中工作。初始化lock validator后,初始化cgroups并设置canary值,我们可以看到setup_arch函数的调用。 你可能还记得,这个函数(定义在arch/x86/kernel/setup.c)准备/初始化特定于体系结构的东西(例如它为bss部分保留一个位置,为initrd保留一个位置,解析内核命令行以及许多其他事情)。除此之外,我们还可以找到一些时间管理相关的功能。 首先是: x86_init.timers.wallclock_init(); 我们在描述Linux内核初始化的章节中已经看到了x86_init结构。此结构包含指向不同平台的默认设置功能的指针,如 Intel MID,Intel CE4100 等x86_init结构定义在arch/x86/kernel/x86_init.c,正如您所看到的,它默认确定标准PC硬件。 我们可以看到,x86_init结构具有x86_init_ops类型,它为平台特定的设置提供了一组函数,如保留标准资源,平台特定的内存设置,中断处理程序的初始化等。这种结构如下所示: struct x86_init_ops { struct x86_init_resources resources; struct x86_init_mpparse mpparse; struct x86_init_irqs irqs; struct x86_init_oem oem; struct x86_init_paging paging; struct x86_init_timers timers; struct x86_init_iommu iommu; struct x86_init_pci pci; struct x86_hyper_init hyper; struct x86_init_acpi acpi; }; 备注: 新增以下两个成员 ...

2019-08-07 · 3 min · 631 words

sysctl-查询修改Linux内核参数

 sysctl命令可以_实时_(runtime)查看和修改linux 内核参数。这个命令可以在大多数发行版本找到, 另外内核参数,也可以通过procfs 文件系统,在 /proc/sys/kernel下 进行查看和修改。 查看指定参数 # sysctl kernel.sched_child_runs_firstkernel.sched_child_runs_first = 0 查看所有参数 # sysctl -a |moresysctl: reading key "net.ipv6.conf.all.stable_secret"sysctl: reading key "net.ipv6.conf.default.stable_secret"abi.vsyscall32 = 1crypto.fips_enabled = 0debug.exception-trace = 1debug.kprobes-optimization = 1 修改指定参数 # sysctl -w kernel.sched_child_runs_first=1 kernel.sched_child_runs_first = 1 注意等号前后不能有空格 修改含多个值的参数 # sysctl -w net.ipv4.ip_local_port_range="1025 60999"net.ipv4.ip_local_port_range = 1025 60999 通过修改procfs 文件系统实现 修改指定参数 # echo 1 > /proc/sys/kernel/sched_child_runs_first# sysctl kernel.sched_child_runs_firstkernel.sched_child_runs_first = 1 修改含多个值的参数 # echo "32768 60999" > /proc/sys/net/ipv4/ip_local_port_range# sysctl net.ipv4.ip_local_port_rangenet.ipv4.ip_local_port_range = 32768 60999 持久化设置 以上修改是临时性的,机器重启后失效,如果要持久化保存,可修改/etc/sysctl.conf # cat /etc/sysctl.confkernel.sched_child_runs_first=1 修改完毕后,使用以下命令使得参数立即生效 ...

2019-08-06 · 1 min · 207 words

asm-offset.h生成过程

asm-offset.h 文件 asm-offset.h 文件是在内核编译过程中生成的,生成过程 之前整理了一份笔记 TASK_threadsp的实现及asm-offsets.h, 其中涉及sed处理包含在内核代码 /scripts/Makefile.lib的sed-offsets中,工作是将生成的asm-offset.s转化为asm-offset.h。 /scripts/Makefile.lib ... # ASM offsets # --------------------------------------------------------------------------- # Default sed regexp - multiline due to syntax constraints # # Use [:space:] because LLVM's integrated assembler inserts <tab> around # the .ascii directive whereas GCC keeps the <space> as-is. define sed-offsets 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \ /^->/{s:->#\(.*\):/* \1 */:; \ s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:->::; p;}' endef ...

2019-08-05 · 3 min · 591 words

TASK_threadsp的实现及asm-offsets.h

主动调度与上下文切换 在学习极客时间刘超《趣谈Linux操作系统》 16 节时,讲到了主动调度, 通过__schedule() 函数让出cpu三个步骤: 1. 取出任务队列; 2. 从队列取下一个任务; 3. 进行上下文切换; 其中第三步中上下文切换中 调用switch_to函数, 通过调用switch_to_asm函数完成栈顶执政寄存器的交换。 代码如下: /arch/x86/include/asm/switch_to.h #define switch_to(prev, next, last) \ do { \ prepare_switch_to(next); \ \ ((last) = __switch_to_asm((prev), (next))); \ } while (0) /arch/x86/entry/entry_64.S ENTRY(__switch_to_asm) UNWIND_HINT_FUNC 。。。 /* switch stack */ movq %rsp, TASK_threadsp(%rdi) movq TASK_threadsp(%rsi), %rsp 。。。。 END(__switch_to_asm) 其中 %rdi代表第一个参数, %rsi代表第二个参数, 分别代表 prev task, next task 将当前栈顶指针放入prev task_struct 结构 thread_struct的 sp0 中。 将next_task栈顶 指做为当前栈顶指针,完成切换。 关于 TASK_threadsp,涉及以下几个文件:(当然一开始的时候正是因为找不到才有了有序寻找答案的过程) ...

2019-07-21 · 3 min · 507 words

Linux 进程,线程的调度策略API

LINUX进程调度: 调度策略: 实时进程的调度策略: SCHED_FIFO SCHED_RR SCHED_DEADLINE 普通进程的调度策略: SCHED_NORMAL SCHED_BATCH SCHED_IDLE 调度类: stop_sched_class dl_sched_class rt_sched_class fair_sched_class idle_sched_class CFS调度策略: 普通进程使用的调度策略CFS调度策略,通过平衡各个进程vruntime来实现公平的调度, CFS维护了一个以时间为顺序的红黑树, 对处理器需求时间最多的,vruntime最小的存放在树的最左端. CPU取出运行完毕后,如果进程还在运行,增加运行时间计算vruntime后插会红黑树。 CFS相关结构: cfs_rq队列中存放树根节点和最左端节点rb_root_cached,每个节点都包含在 sched_entity,中,sched_entity中存放vruntime做为红黑树的索引, sched_entity 又属于 task_struct, task_struct 中通过 sched_class 指定调度类 具体可以参考是极客时间 《趣谈操作系统》 15-17节 LINUX进程调度API: sched - overview of CPU scheduling nice(2) 设置当前进程线程的优先级 getpriority(2) 获取指定用户的进程,进程组,线程优先级 setpriority(2) 设置指定用户的进程,进程组,线程优先级 sched_setscheduler(2) 设置调度策略 sched_getscheduler(2) 获取调度策略 sched_setparam(2) 设置调度参数. sched_getparam(2) 获取调度参数. sched_get_priority_max(2) 返回指定调度策略的优先级最大值 sched_get_priority_min(2) 返回指定调度策略的优先级最小值 sched_rr_get_interval(2) 获取SCHED_RR调度策略时间片长度 sched_yield(2) 主动让出CPU sched_setaffinity(2) (Linux-specific) 线程设置到指定CPU sched_getaffinity(2) (Linux-specific) 获取相关CPU设置 sched_setattr(2) 设置调度策略和参数 sched_getattr(2) 获取调度策略和参数 Posix Threads API : ...

2019-07-16 · 6 min · 1127 words

函数栈的调用

 本篇主要通过反汇编与GDB两种方式分析函数栈的使用过程。 反编译方法: gcc -S Stop after the stage of compilation proper; do not assemble. The output is in theform of an assembler code file for each non-assembler input file specified.By default, the assembler file name for a source file is made by replacing the suffix.c, .i, etc., with .s.Input files that don't require compilation are ignored. gcc -S -o [source].s [source].c objdump gcc stack.c -o stack.oobjdump -S ./stack.o > stack_objdump.s 编译环境: 环境: cenos7, X86_64 ...

2019-07-07 · 9 min · 1777 words

获取进程信息相关命令

任务ID: pid: 进程ID tid:线程ID tgid:主线程ID 显示线程需要增加 L参数 ps -eLo pid,tid,tgid,pgrp,args 任务状态: 进程状态描述: D uninterruptible sleep (usually IO) R running or runnable (on run queue) S interruptible sleep (waiting for an event to complete) T stopped by job control signal t stopped by debugger during the tracing W paging (not valid since the 2.6.xx kernel) X dead (should never be seen) Z defunct (“zombie”) process, terminated but not reaped by its parent ...

2019-07-03 · 2 min · 350 words

linux 任务状态定义

结构定义: Linux task_struct 结构中 涉及进程状态的属性有三个,其中进程对应的状态分为两类, 一类是运行中状态, 另一类是进程退出状态。 struct task_struct { ... /* -1 unrunnable, 0 runnable, >0 stopped: */ volatile long state; int exit_state; unsigned int flags; ... } 状态说明: TASK_RUNNING 等待运行状态 TASK_INTERRUPTIBLE 可中断睡眠状态 TASK_UNINTERRUPTIBLE 不可中断睡眠状态 TASK_STOPPED 停止状态(收到 SIGSTOP、SIGTTIN、SIGTSTP 、 SIG.TTOU信号后状态) TASK_TRACED 被调试状态 TASK_KILLABLE 新可中断睡眠状态 TASK_PARKED kthread_park使用的特殊状态 TASK_NEW 创建任务临时状态 TASK_DEAD 任务退出状态 TASK_WAKING 被唤醒状态 TASK_IDLE 任务空闲状态 /* * Task state bitmask. NOTE! These bits are also * encoded in fs/proc/array.c: get_task_state(). * * We have two separate sets of flags: task->state * is about runnability, while task->exit_state are * about the task exiting. Confusing, but this way * modifying one set can't modify the other one by * mistake. */ /* Used in tsk->state: */ #define TASK_RUNNING 0x0000 #define TASK_INTERRUPTIBLE 0x0001 #define TASK_UNINTERRUPTIBLE 0x0002 #define __TASK_STOPPED 0x0004 #define __TASK_TRACED 0x0008 /* Used in tsk->exit_state: */ #define EXIT_DEAD 0x0010 #define EXIT_ZOMBIE 0x0020 #define EXIT_TRACE (EXIT_ZOMBIE | EXIT_DEAD) /* Used in tsk->state again: */ #define TASK_PARKED 0x0040 #define TASK_DEAD 0x0080 #define TASK_WAKEKILL 0x0100 #define TASK_WAKING 0x0200 #define TASK_NOLOAD 0x0400 #define TASK_NEW 0x0800 #define TASK_STATE_MAX 0x1000 /* Convenience macros for the sake of set_current_state: */ #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE) #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED) #define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED) #define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD) /* Convenience macros for the sake of wake_up(): */ #define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE) /* get_task_state(): */ #define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \ TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \ __TASK_TRACED | EXIT_DEAD | EXIT_ZOMBIE | \ TASK_PARKED) 相关代码: 下面通过内核代码,看下任务状态转换的一个大致过程。 ...

2019-06-29 · 4 min · 671 words

ELF 文件格式分析

定义: ELF: Executable and Linkable Format ELF文件常见的三种文件类型: relocatable (可重定位) executable(可执行) shared object(共享目标) core dumps (核心转储) [root@centosgpt 10]# file process.oprocess.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped[root@centosgpt 10]# file dynamiccreateprocessdynamiccreateprocess: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=d6fa7d670a47b7aaf05d17c92c82508bcabc48dc, not stripped[root@centosgpt 10]# file libdynamicprocess.solibdynamicprocess.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0a9fb4457819ecf54d9762f3aff5eda0c19600fc, not stripped 组成: ELF header program header table section header table binary data 常用的elf文件分析工具, readelf, objdump, nm, hexdump ...

2019-06-11 · 25 min · 5113 words

Linux下实现一个系统调用

环境: 环境: cenos7 kernel: 3.10.0-862.el7.x86_64 gcc: gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) 新版内核: linux-5.2-rc2 准备: 安装相关软件: yum install make automake vim perl openssl* elfutils-libelf- curl gcc wget flex git build-essential ncurses-devel xz-utils libssl-dev bc flex libelf-dev bison elfutils-libelf-devel -y 下载内核源码并解压: tar -xf linux-5.2-rc2.tar.gz 编写系统调用: 新增系统调用表条目: cp syscall_64.tbl syscall_64.tbl.backup linux-5.2-rc2/arch/x86/entry/syscalls/syscall_64.tbl 新增下面一条 + 434 common iadd_test __x64_sys_iadd_test 其中434为新增的调用号 增加函数声明 linux-5.2-rc2/include/linux/syscalls.h:新增一行 asmlinkage long sys_iadd_test(int one, int two); 新增系统调用定义 kernel/linux-5.2-rc2/fs/iadd_test.c #include <linux/printk.h> #include <linux/syscalls.h> #include "internal.h" long do_iadd(const int one, const int two ) { long sum = 0L; sum = one + two; return sum; } SYSCALL_DEFINE2(iadd_test, const int, one, const int, two) { printk("call iaddtest..."); return do_iadd(one, two); } 修改Makfile 增加iadd_test.o ...

2019-06-02 · 2 min · 342 words