Skip to the content.

什么地方需要检查 signal_pending

基本机制

在内核很多调用 signal_pending 的地方,例如 kvm_arch_vcpu_ioctl_run 中

		if (signal_pending(current)) {
			r = -EINTR;
			kvm_run->exit_reason = KVM_EXIT_INTR;
			++vcpu->stat.signal_exits;
		}

signal pending

  1. 调用 signal_pending : 在无限循环中间,需要等待可以让用户程序 kill
  2. 调用 fatal_signal_pending :

实际上的代码在 kernel/entry/ irqentry_exit_to_user_mode 和 syscall_exit_to_user_mode

需要的分析的细节:

  1. generic_file_buffered_read 中间会调用 fatal_signal_pending,那么各种检查函数的要求是什么 ?
➜  linux git:(master) ag signal_pending | wc -l
741

为什么 generic_perform_write 调用 fatal_signal_pending 而不是 signal_pending 啊

分析一下这个基本函数

static inline int task_sigpending(struct task_struct *p)
{
	return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
}

static inline int signal_pending(struct task_struct *p)
{
	/*
	 * TIF_NOTIFY_SIGNAL isn't really a signal, but it requires the same
	 * behavior in terms of ensuring that we break out of wait loops
	 * so that notify signal callbacks can be processed.
	 */
	if (unlikely(test_tsk_thread_flag(p, TIF_NOTIFY_SIGNAL)))
		return 1;
	return task_sigpending(p);
}

为什么 signal_pending 的

/*
 * Reclaims as many pages from the given memcg as possible.
 *
 * Caller is responsible for holding css reference for memcg.
 */
static int mem_cgroup_force_empty(struct mem_cgroup *memcg)
{
	int nr_retries = MAX_RECLAIM_RETRIES;

	/* we call try-to-free pages for make this cgroup empty */
	lru_add_drain_all();

	drain_all_stock(memcg);

	/* try to free all pages in this cgroup */
	while (nr_retries && page_counter_read(&memcg->memory)) {
		if (signal_pending(current))
			return -EINTR;

		if (!try_to_free_mem_cgroup_pages(memcg, 1, GFP_KERNEL,
						  MEMCG_RECLAIM_MAY_SWAP))
			nr_retries--;
	}

	return 0;
}

问题并不简单

[ ] 处理被打断的事情,也许是交给 fwrite 做的,可以测试一下

参考下这个

https://devopedia.org/linux-signals

是不是 while 循环中就该检查,还是

sleep 的位置都改检查?

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。