linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Move accounting function calls out of critical vm code paths
@ 2005-01-06  0:55 Christoph Lameter
  2005-01-10  2:43 ` Matt Mackall
  0 siblings, 1 reply; 2+ messages in thread
From: Christoph Lameter @ 2005-01-06  0:55 UTC (permalink / raw)
  To: torvads; +Cc: akpm, jlan, linux-kernel

The new accounting patches add function calls to critical code paths.
These statistics have traditionally be gathered during
the timer tick. Accounting is dependent on stime being incremented:

void acct_update_integrals(void)
{
        struct task_struct *tsk = current;

        if (likely(tsk->mm)) {
                long delta = tsk->stime - tsk->acct_stimexpd;

                tsk->acct_stimexpd = tsk->stime;
                tsk->acct_rss_mem1 += delta * tsk->mm->rss;
                tsk->acct_vm_mem1 += delta * tsk->mm->total_vm;
        }
}

If stime has not increased then delta == 0 and nothing happens just
a multiplication with zero....

Thus one may move the calls to the timer interrupt and only call
acct_update_integrals if stime has been incremented. This will avoid
having to spent time to gather statistics in the hot paths of the vm.

One disadvantage is that rss etc may now peak between stime increments without
being noticed. But I think we are mostly interested in prolonged memory use
rather than accurate data on the max rss ever reached.

Signed-off-by: Christoph Lameter <clameter@sgi.com>

Index: linux-2.6.10/kernel/timer.c
===================================================================
--- linux-2.6.10.orig/kernel/timer.c	2005-01-05 16:23:39.000000000 -0800
+++ linux-2.6.10/kernel/timer.c	2005-01-05 16:35:51.000000000 -0800
@@ -32,6 +32,7 @@
 #include <linux/jiffies.h>
 #include <linux/cpu.h>
 #include <linux/syscalls.h>
+#include <linux/acct.h>

 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -815,6 +816,10 @@
 		if (psecs / HZ >= p->signal->rlim[RLIMIT_CPU].rlim_max)
 			send_sig(SIGKILL, p, 1);
 	}
+	if (system) {
+		acct_update_integrals(p);
+		update_mem_hiwater(p);
+	}
 }

 static inline void do_it_virt(struct task_struct * p, unsigned long ticks)
Index: linux-2.6.10/mm/memory.c
===================================================================
--- linux-2.6.10.orig/mm/memory.c	2005-01-05 16:23:39.000000000 -0800
+++ linux-2.6.10/mm/memory.c	2005-01-05 16:23:41.000000000 -0800
@@ -46,7 +46,6 @@
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
 #include <linux/rmap.h>
-#include <linux/acct.h>
 #include <linux/module.h>
 #include <linux/init.h>

@@ -739,7 +738,6 @@
 	tlb = tlb_gather_mmu(mm, 0);
 	unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details);
 	tlb_finish_mmu(tlb, address, end);
-	acct_update_integrals();
 	spin_unlock(&mm->page_table_lock);
 }

@@ -1336,8 +1334,6 @@
 			mm->anon_rss--;
 		if (PageReserved(old_page)) {
 			++mm->rss;
-			acct_update_integrals();
-			update_mem_hiwater();
 		} else
 			page_remove_rmap(old_page);
 		break_cow(vma, new_page, address, page_table);
@@ -1620,8 +1616,6 @@
 		remove_exclusive_swap_page(page);

 	mm->rss++;
-	acct_update_integrals();
-	update_mem_hiwater();

 	pte = mk_pte(page, vma->vm_page_prot);
 	if (write_access && can_share_swap_page(page)) {
@@ -1688,8 +1682,6 @@
 			goto out;
 		}
 		mm->rss++;
-		acct_update_integrals();
-		update_mem_hiwater();
 		entry = maybe_mkwrite(pte_mkdirty(mk_pte(page,
 							 vma->vm_page_prot)),
 				      vma);
@@ -1799,8 +1791,6 @@
 	if (pte_none(*page_table)) {
 		if (!PageReserved(new_page))
 			++mm->rss;
-		acct_update_integrals();
-		update_mem_hiwater();

 		flush_icache_page(vma, new_page);
 		entry = mk_pte(new_page, vma->vm_page_prot);
@@ -2124,10 +2114,8 @@
  * update_mem_hiwater
  *	- update per process rss and vm high water data
  */
-void update_mem_hiwater(void)
+void update_mem_hiwater(struct task_struct *tsk)
 {
-	struct task_struct *tsk = current;
-
 	if (tsk->mm) {
 		if (tsk->mm->hiwater_rss < tsk->mm->rss)
 			tsk->mm->hiwater_rss = tsk->mm->rss;
Index: linux-2.6.10/kernel/exit.c
===================================================================
--- linux-2.6.10.orig/kernel/exit.c	2005-01-05 16:23:38.000000000 -0800
+++ linux-2.6.10/kernel/exit.c	2005-01-05 16:23:41.000000000 -0800
@@ -801,8 +801,8 @@
 		ptrace_notify((PTRACE_EVENT_EXIT << 8) | SIGTRAP);
 	}

-	acct_update_integrals();
-	update_mem_hiwater();
+	acct_update_integrals(current);
+	update_mem_hiwater(current);
 	group_dead = atomic_dec_and_test(&tsk->signal->live);
 	if (group_dead)
 		acct_process(code);
Index: linux-2.6.10/mm/swapfile.c
===================================================================
--- linux-2.6.10.orig/mm/swapfile.c	2005-01-05 16:23:39.000000000 -0800
+++ linux-2.6.10/mm/swapfile.c	2005-01-05 16:23:41.000000000 -0800
@@ -24,7 +24,6 @@
 #include <linux/module.h>
 #include <linux/rmap.h>
 #include <linux/security.h>
-#include <linux/acct.h>
 #include <linux/backing-dev.h>
 #include <linux/syscalls.h>

@@ -437,8 +436,6 @@
 	set_pte(dir, pte_mkold(mk_pte(page, vma->vm_page_prot)));
 	page_add_anon_rmap(page, vma, address);
 	swap_free(entry);
-	acct_update_integrals();
-	update_mem_hiwater();
 }

 /* vma->vm_mm->page_table_lock is held */
Index: linux-2.6.10/include/linux/mm.h
===================================================================
--- linux-2.6.10.orig/include/linux/mm.h	2005-01-05 16:23:38.000000000 -0800
+++ linux-2.6.10/include/linux/mm.h	2005-01-05 16:31:49.000000000 -0800
@@ -835,7 +835,7 @@
 }

 /* update per process rss and vm hiwater data */
-extern void update_mem_hiwater(void);
+extern void update_mem_hiwater(struct task_struct *tsk);

 #ifndef CONFIG_DEBUG_PAGEALLOC
 static inline void
Index: linux-2.6.10/include/linux/acct.h
===================================================================
--- linux-2.6.10.orig/include/linux/acct.h	2005-01-05 16:23:38.000000000 -0800
+++ linux-2.6.10/include/linux/acct.h	2005-01-05 16:31:33.000000000 -0800
@@ -120,12 +120,12 @@
 struct super_block;
 extern void acct_auto_close(struct super_block *sb);
 extern void acct_process(long exitcode);
-extern void acct_update_integrals(void);
+extern void acct_update_integrals(struct task_struct *tsk);
 extern void acct_clear_integrals(struct task_struct *tsk);
 #else
 #define acct_auto_close(x)	do { } while (0)
 #define acct_process(x)		do { } while (0)
-#define acct_update_integrals()		do { } while (0)
+#define acct_update_integrals(x)	do { } while (0)
 #define acct_clear_integrals(task)	do { } while (0)
 #endif

Index: linux-2.6.10/kernel/acct.c
===================================================================
--- linux-2.6.10.orig/kernel/acct.c	2005-01-05 16:23:38.000000000 -0800
+++ linux-2.6.10/kernel/acct.c	2005-01-05 16:28:00.000000000 -0800
@@ -534,10 +534,8 @@
  * acct_update_integrals
  *    -  update mm integral fields in task_struct
  */
-void acct_update_integrals(void)
+void acct_update_integrals(struct task_struct *tsk)
 {
-	struct task_struct *tsk = current;
-
 	if (likely(tsk->mm)) {
 		long delta = tsk->stime - tsk->acct_stimexpd;

Index: linux-2.6.10/mm/rmap.c
===================================================================
--- linux-2.6.10.orig/mm/rmap.c	2005-01-05 16:23:39.000000000 -0800
+++ linux-2.6.10/mm/rmap.c	2005-01-05 16:23:41.000000000 -0800
@@ -51,7 +51,6 @@
 #include <linux/swapops.h>
 #include <linux/slab.h>
 #include <linux/init.h>
-#include <linux/acct.h>
 #include <linux/rmap.h>
 #include <linux/rcupdate.h>

@@ -607,7 +606,6 @@
 	}

 	mm->rss--;
-	acct_update_integrals();
 	page_remove_rmap(page);
 	page_cache_release(page);

@@ -712,7 +710,6 @@

 		page_remove_rmap(page);
 		page_cache_release(page);
-		acct_update_integrals();
 		mm->rss--;
 		(*mapcount)--;
 	}
Index: linux-2.6.10/mm/mmap.c
===================================================================
--- linux-2.6.10.orig/mm/mmap.c	2005-01-05 16:23:39.000000000 -0800
+++ linux-2.6.10/mm/mmap.c	2005-01-05 16:24:24.000000000 -0800
@@ -21,7 +21,6 @@
 #include <linux/hugetlb.h>
 #include <linux/profile.h>
 #include <linux/module.h>
-#include <linux/acct.h>
 #include <linux/mount.h>
 #include <linux/mempolicy.h>
 #include <linux/rmap.h>
@@ -1021,8 +1020,6 @@
 					pgoff, flags & MAP_NONBLOCK);
 		down_write(&mm->mmap_sem);
 	}
-	acct_update_integrals();
-	update_mem_hiwater();
 	return addr;

 unmap_and_free_vma:
@@ -1369,8 +1366,6 @@
 	if (vma->vm_flags & VM_LOCKED)
 		vma->vm_mm->locked_vm += grow;
 	__vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, grow);
-	acct_update_integrals();
-	update_mem_hiwater();
 	anon_vma_unlock(vma);
 	return 0;
 }
@@ -1434,8 +1429,6 @@
 	if (vma->vm_flags & VM_LOCKED)
 		vma->vm_mm->locked_vm += grow;
 	__vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file, grow);
-	acct_update_integrals();
-        update_mem_hiwater();
 	anon_vma_unlock(vma);
 	return 0;
 }
@@ -1823,8 +1816,6 @@
 		mm->locked_vm += len >> PAGE_SHIFT;
 		make_pages_present(addr, addr + len);
 	}
-	acct_update_integrals();
-	update_mem_hiwater();
 	return addr;
 }

Index: linux-2.6.10/mm/mremap.c
===================================================================
--- linux-2.6.10.orig/mm/mremap.c	2005-01-05 16:23:39.000000000 -0800
+++ linux-2.6.10/mm/mremap.c	2005-01-05 16:25:30.000000000 -0800
@@ -16,7 +16,6 @@
 #include <linux/fs.h>
 #include <linux/highmem.h>
 #include <linux/security.h>
-#include <linux/acct.h>
 #include <linux/syscalls.h>

 #include <asm/uaccess.h>
@@ -251,9 +250,6 @@
 					   new_addr + new_len);
 	}

-	acct_update_integrals();
-	update_mem_hiwater();
-
 	return new_addr;
 }

@@ -390,8 +386,6 @@
 				make_pages_present(addr + old_len,
 						   addr + new_len);
 			}
-			acct_update_integrals();
-			update_mem_hiwater();
 			ret = addr;
 			goto out;
 		}
Index: linux-2.6.10/fs/exec.c
===================================================================
--- linux-2.6.10.orig/fs/exec.c	2005-01-05 16:23:38.000000000 -0800
+++ linux-2.6.10/fs/exec.c	2005-01-05 16:34:16.000000000 -0800
@@ -1165,8 +1165,8 @@

 		/* execve success */
 		security_bprm_free(bprm);
-		acct_update_integrals();
-		update_mem_hiwater();
+		acct_update_integrals(current);
+		update_mem_hiwater(current);
 		kfree(bprm);
 		return retval;
 	}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Move accounting function calls out of critical vm code paths
  2005-01-06  0:55 Move accounting function calls out of critical vm code paths Christoph Lameter
@ 2005-01-10  2:43 ` Matt Mackall
  0 siblings, 0 replies; 2+ messages in thread
From: Matt Mackall @ 2005-01-10  2:43 UTC (permalink / raw)
  To: Christoph Lameter; +Cc: torvads, akpm, jlan, linux-kernel

On Wed, Jan 05, 2005 at 04:55:14PM -0800, Christoph Lameter wrote:

> One disadvantage is that rss etc may now peak between stime
> increments without being noticed. But I think we are mostly
> interested in prolonged memory use rather than accurate data on the
> max rss ever reached.

This has the downside that applications may die well after the event
that caused the excess. Also, I can see situations in RT where strict
limits are put in place to ensure that particular apps are never
starved so strict accounting is occassionally desireable.

Perhaps we could do the accounting on the fly iff we have an rlimit in
the first place and we're already over half of it? Such strict
accounting could triggered by a process flag turned off and on inside
acct_update_integrals.

One also wonders if once per timer tick is more processing for compute
intensive workloads.

Finally, do { } while (0); is a bit of cargo cult. The compilers no
longer warn for empty statements so a null #define is fine.

-- 
Mathematics is the supreme nostalgia of our time.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-01-10  2:43 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-06  0:55 Move accounting function calls out of critical vm code paths Christoph Lameter
2005-01-10  2:43 ` Matt Mackall

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).