[RFC, PATCH] cond_resched() added to close_files()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When a process exits, it might spend a lot of time in close_files() closing 
thousand of files.

This is bad for latency, and in some cases can trigger 'BUG: soft lockup 
detected on CPU#0!'

Call Trace: <IRQ> <ffffffff8024dafa>{softlockup_tick+250}
       <ffffffff80236cd7>{update_process_times+87} 
<ffffffff80215ed3>{smp_local_timer_interrupt+35}
       <ffffffff80216411>{smp_apic_timer_interrupt+65} 
<ffffffff8020a866>{apic_timer_interrupt+98} <EOI>
       <ffffffff803a7100>{sock_destroy_inode+0} 
<ffffffff803e4b1f>{tcp_send_fin+207}
       <ffffffff803e4ac4>{tcp_send_fin+116} <ffffffff803d988a>{tcp_close+698}
       <ffffffff803f4a07>{inet_release+87} <ffffffff803a84e9>{sock_release+25}
       <ffffffff803a87f5>{sock_close+53} <ffffffff802767a8>{__fput+88}
       <ffffffff8027382d>{filp_close+93} 
<ffffffff8022ee2e>{put_files_struct+110}
       <ffffffff8023025a>{do_exit+650} 
<ffffffff80237bee>{__dequeue_signal+478}
       <ffffffff80230998>{do_group_exit+200} 
<ffffffff80239c6a>{get_signal_to_deliver+1178}
       <ffffffff80209d47>{sysret_signal+28} <ffffffff80209001>{do_signal+129}
       <ffffffff8028d623>{dput+35} <ffffffff803a92db>{sys_accept+443}
       <ffffffff80241eec>{add_wait_queue+28} <ffffffff802ec581>{__up_write+33}
       <ffffffff80209d47>{sysret_signal+28} 
<ffffffff8020a033>{ptregscall_common+103}

This patch makes sure a cond_resched() call is done every 32 (or 64) files 
closed. This also helps reducing number of files waiting in RCU queues for 
final freeing as call_rcu() might have called force_quiescent_state()

Signed-off-by: Eric Dumazet <[email protected]>
--- a/kernel/exit.c	2006-05-02 17:31:39.000000000 +0200
+++ b/kernel/exit.c	2006-05-02 17:32:06.000000000 +0200
@@ -445,20 +445,21 @@
 		set = fdt->open_fds->fds_bits[j++];
 		while (set) {
 			if (set & 1) {
 				struct file * file = xchg(&fdt->fd[i], NULL);
 				if (file)
 					filp_close(file, files);
 			}
 			i++;
 			set >>= 1;
 		}
+		cond_resched();
 	}
 }
 
 struct files_struct *get_files_struct(struct task_struct *task)
 {
 	struct files_struct *files;
 
 	task_lock(task);
 	files = task->files;
 	if (files)

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux