[英]Why doesn't pgrep find my process if I supply too long a search term?
[英]Why does my process take too long to die?
基本上,我在PowerPC(Freescale e500mc)上使用Linux 2.6.34。 我有一个进程(一种内部开发的VM),它使用大约2.25 G的锁住VM。 当我杀死它时,我注意到终止过程最多需要2分钟。
我调查了一下。 首先,我关闭了所有打开的文件描述符,但这似乎没有什么不同。 然后,我在内核中添加了一些printk,通过它我发现所有延迟都来自内核解锁我的VMA。 页面之间的延迟是一致的,我通过反复检查/ proc / meminfo中的锁定页面数来验证这一点。 我检查过分配了那么多内存的程序,一旦我发出信号,它们就会全部消失。
您认为我现在应该检查什么? 多谢您的回覆。
编辑:我必须找到一种方法来共享有关该问题的更多信息,所以我在下面的程序中编写了此代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <sys/time.h>
#define MAP_PERM_1 (PROT_WRITE | PROT_READ | PROT_EXEC)
#define MAP_PERM_2 (PROT_WRITE | PROT_READ)
#define MAP_FLAGS (MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE)
#define PG_LEN 4096
#define align_pg_32(addr) (addr & 0xFFFFF000)
#define num_pg_in_range(start, end) ((end - start + 1) >> 12)
inline void __force_pgtbl_alloc(unsigned int start)
{
volatile int *s = (int *) start;
*s = *s;
}
int __map_a_page_at(unsigned int start, int whichperm)
{
int perm = whichperm ? MAP_PERM_1 : MAP_PERM_2;
if(MAP_FAILED == mmap((void *)start, PG_LEN, perm, MAP_FLAGS, 0, 0)){
fprintf(stderr,
"mmap failed at 0x%x: %s.\n",
start, strerror(errno));
return 0;
}
return 1;
}
int __mlock_page(unsigned int addr)
{
if (mlock((void *)addr, (size_t)PG_LEN) < 0){
fprintf(stderr,
"mlock failed on page: 0x%x: %s.\n",
addr, strerror(errno));
return 0;
}
return 1;
}
void sigint_handler(int p)
{
struct timeval start = {0 ,0}, end = {0, 0}, diff = {0, 0};
gettimeofday(&start, NULL);
munlockall();
gettimeofday(&end, NULL);
timersub(&end, &start, &diff);
printf("Munlock'd entire VM in %u secs %u usecs.\n",
diff.tv_sec, diff.tv_usec);
exit(0);
}
int make_vma_map(unsigned int start, unsigned int end)
{
int num_pg = num_pg_in_range(start, end);
if (end < start){
fprintf(stderr,
"Bad range: start: 0x%x end: 0x%x.\n",
start, end);
return 0;
}
for (; num_pg; num_pg --, start += PG_LEN){
if (__map_a_page_at(start, num_pg % 2) && __mlock_page(start))
__force_pgtbl_alloc(start);
else
return 0;
}
return 1;
}
void display_banner()
{
printf("-----------------------------------------\n");
printf("Virtual memory allocator. Ctrl+C to exit.\n");
printf("-----------------------------------------\n");
}
int main()
{
unsigned int vma_start, vma_end, input = 0;
int start_end = 0; // 0: start; 1: end;
display_banner();
// Bind SIGINT handler.
signal(SIGINT, sigint_handler);
while (1){
if (!start_end)
printf("start:\t");
else
printf("end:\t");
scanf("%i", &input);
if (start_end){
vma_end = align_pg_32(input);
make_vma_map(vma_start, vma_end);
}
else{
vma_start = align_pg_32(input);
}
start_end = !start_end;
}
return 0;
}
如您所见,该程序接受虚拟地址范围,每个范围由开始和结束定义。 然后,通过为相邻页面赋予不同的权限,可以将每个范围进一步细分为页面大小的VMA。 中断(使用SIGINT)程序将触发对munlockall()的调用,并适当记录该过程的完成时间。
现在,当我在Linux版本为2.6.34的飞思卡尔e500mc上以0x30000000-0x35000000的范围运行它时,我得到的munlockall()总时间几乎为45秒。 但是,如果我以较小的起始范围以随机顺序执行相同的操作(即不一定增加地址),以使页面总数(和锁定的VMA)大致相同,请观察munlockall()的总时间不超过4秒。
我在使用Linux 2.6.34的x86_64上尝试了相同的操作,并且我的程序针对-m32参数进行了编译,尽管变化不如ppc明显,但第一种情况仍为8秒,第二种情况则为第二秒案件。
我一方面在Linux 2.6.10上尝试了该程序,另一方面在3.19上尝试了该程序,看来这些巨大的区别在那里不存在。 而且,munlockall()总是在不到一秒钟的时间内完成。
因此,似乎该问题(无论是什么问题)仅在2.6.34版本的Linux内核周围存在。
您说虚拟机是内部开发的。 这是否意味着您有权访问源? 我将从检查是否有阻止它立即终止以防止数据丢失的任何内容开始。
否则,您可能会尝试提供更多信息吗? 您可能还想看看: https : //unix.stackexchange.com/,因为它们更适合于解决Linux内核可能遇到的任何问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.