pid_max的分析和修改

pid_max 内核源码处理分析

1以linux-3.2.6为例子分析 2 3init/main.c: asmlinkage void __init start_kernel(void) -> kernel/pid.c: void __init pidmap_init(void) 4 5void __init pidmap_init(void) 6{ 7 /* bump default and minimum pid_max based on number of cpus */ 8 pid_max = min(pid_max_max, max_t(int, pid_max, 9 PIDS_PER_CPU_DEFAULT * num_possible_cpus())); 10 pid_max_min = max_t(int, pid_max_min, 11 PIDS_PER_CPU_MIN * num_possible_cpus()); 12 pr_info("pid_max: default: %u minimum: %u\n", pid_max, pid_max_min); 13 14 init_pid_ns.pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL); 15 /* Reserve PID 0. We never call free_pidmap(0) */ 16 set_bit(0, init_pid_ns.pidmap[0].page); 17 atomic_dec(&init_pid_ns.pidmap[0].nr_free); 18 19 init_pid_ns.pid_cachep = KMEM_CACHE(pid, 20 SLAB_HWCACHE_ALIGN | SLAB_PANIC); 21} 22 231、选出最大的pid_max 24max_t(int, pid_max, PIDS_PER_CPU_DEFAULT * num_possible_cpus()) 25 261.1、默认的pid_max 27 28int pid_max = PID_MAX_DEFAULT; 29#define PID_MAX_DEFAULT (CONFIG_BASE_SMALL ? 0x1000 : 0x8000) 30 31也就是说如果没有配置base_small,则pid_max是0x8000,即32768。 32 331.2、计算cpu默认分配的pid总数 34 35#define PIDS_PER_CPU_DEFAULT 1024 //每个cpu默认是1024个pid。 36#define num_possible_cpus() cpumask_weight(cpu_possible_mask) //cpu总数 37因此总的pid数就是 PIDS_PER_CPU_DEFAULT * num_possible_cpus() 38 39因此第一步是先从这两个里面选出最大的那个,只有超过(32768/1024=32)32个cpu,才会用到cpu算出的pid总数,否则就是默认的。 40 412、系统总pid限制,即pid_max_max 42 43int pid_max_max = PID_MAX_LIMIT; 44#define PID_MAX_LIMIT (CONFIG_BASE_SMALL ? PAGE_SIZE * 8 : \ 45 (sizeof(long) > 4 ? 4 * 1024 * 1024 : PID_MAX_DEFAULT)) 46 47也既是最终的pid_max是不能超过pid_max_max,即不能超过limit(如果配置了base_small,则为page_size*8个pid。没配置的情况下,如果是64位的,则为4*1024*1024=4194304个pid。否则就是默认的PID_MAX_DEFAULT,即(0x100或0x800)

总结:
在不开启小内核的情况下,32为系统最大的pid个数是32768,实际的pid个数会根据cpu个数来调节,如果cpu个数小于32个,则实际的pid个数为32768,如果超过32个,则实际的pid个数为1024*cpus。

如何调节pid_max (也可以手动设置)

1.改变cpus

前面已经说到pid_max的来源,可以调节pid_max的途径就是改变cpus,那么cpus是如何确定的呢?

cpus个数并非实际的cpu个数,而是possible cpus,即可用的最高cpu总数(有些热插拔的cpu还没有插进来,预留用的)

以x86为例子,查看possible cpus的来源

1init/main.c start_kernel -> arch/x86/kernel/setup.c: void __init setup_arch -> arch/x86/kernel/smpboot.c __init void prefill_possible_map: 2 3... 4 if (setup_possible_cpus == -1) { 5 possible = num_processors; 6#ifdef CONFIG_HOTPLUG_CPU 7 if (setup_max_cpus) 8 possible += disabled_cpus; 9#else 10 if (possible > i) 11 possible = i; 12#endif 13 } else 14 possible = setup_possible_cpus; 15 16 total_cpus = max_t(int, possible, num_processors + disabled_cpus); 17 18可用看到possible可以直接来源于setup_possible_cpus 19 20static int __initdata setup_possible_cpus = -1; 21static int __init _setup_possible_cpus(char *str) 22{ 23 get_option(&str, &setup_possible_cpus); 24 return 0; 25} 26early_param("possible_cpus", _setup_possible_cpus); 27 28可以看到它是可以通过内核参数传递进来的。最终能够手动修改pid个数的地方就是通过修改possible cpus,也就是通过内核参数来修改setup_possible_cpus。 29具体的内核参数就是early_param定义的possible_cpus。 30 31如何知道具体有多少个possible cpus?如下 32 33 printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", 34 possible, max_t(int, possible - num_processors, 0)); 35因此可以通过dmesg | grep Allowing来查看

# 关于CONFIG_BASE_SMALL
如果关闭这个选项,则会减少一部分内核数据结构。但是会减少性能。

2. 手动设置pid_max
  • 临时修改
1echo 327680 > /proc/sys/kernel/pid_max
  • 永久修改
1echo "kernel.pid_max=327680 " >> /etc/sysctl.conf 2sysctl -p

本文转自 https://blog.csdn.net/hawkerou/article/details/71703640,如有侵权,请联系删除。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

Java获得今日零时零分零秒的时间(Date型)

publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS

JS 苹果手机日期显示NaN问题

问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl

Python之time模块的时间戳、时间字符串格式化与转换

Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y