linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christoph Rohland <cr@sap.com>
To: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	MM mailing list <linux-mm@kvack.org>
Subject: [Patch] Do not account shmem pages to the page cache
Date: 07 May 2001 14:43:28 +0200	[thread overview]
Message-ID: <m3y9s9nxcf.fsf@linux.local> (raw)

Hi,

The appended patch does it's own accounting of shmem pages and adjust
the page cache size to take these into account. So now again you will
see shmem pages as used in top/vmstat etc. This confused a lot of
people.

There is a uncertainty in the calculations since the vm may drop pages
behind shmem and the number of shmem pages is estimated too high. This
especially happens on truncate because first the page cache is reduced
and later the shmem readjusts it's count.

To prevent negative cache sizes the adjustment is only done if
shmem_nrpages > page_cache_size.

The latter part of the patch (all the init.c files) also exports the
shmem page number to the shared memory field in meminfo. This means a
change in semantics of this field but apparently a lot of people
interpret this field exactly this way and it was not used any more

The patches are on top of my encapsulation patch.

Greetings
		Christoph

diff -uNr 2.4.4-mSsu/fs/proc/proc_misc.c 2.4.4-mSsua/fs/proc/proc_misc.c
--- 2.4.4-mSsu/fs/proc/proc_misc.c	Sun Apr 29 20:32:52 2001
+++ 2.4.4-mSsua/fs/proc/proc_misc.c	Mon May  7 13:38:53 2001
@@ -140,6 +140,17 @@
 {
 	struct sysinfo i;
 	int len;
+	unsigned int cached, shmem;
+
+	/*
+	 * There may be some inconsistency because shmem_nrpages
+	 * update is delayed to page_cache_size
+	 * We make sure the cached value does not get below zero 
+	 */
+	cached = atomic_read(&page_cache_size);
+	shmem  = atomic_read(&shmem_nrpages);
+	if (shmem < cached)
+		cached -= shmem;
 
 /*
  * display in kilobytes.
@@ -153,8 +164,8 @@
                 "Swap: %8lu %8lu %8lu\n",
                 B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
                 B(i.sharedram), B(i.bufferram),
-                B(atomic_read(&page_cache_size)), B(i.totalswap),
-                B(i.totalswap-i.freeswap), B(i.freeswap));
+		B(cached), B(i.totalswap),
+		B(i.totalswap-i.freeswap), B(i.freeswap));
         /*
          * Tagged format, for easy grepping and expansion.
          * The above will go away eventually, once the tools
@@ -180,7 +191,7 @@
                 K(i.freeram),
                 K(i.sharedram),
                 K(i.bufferram),
-                K(atomic_read(&page_cache_size)),
+		K(cached),
 		K(nr_active_pages),
 		K(nr_inactive_dirty_pages),
 		K(nr_inactive_clean_pages()),
diff -uNr 2.4.4-mSsu/include/linux/shmem_fs.h 2.4.4-mSsua/include/linux/shmem_fs.h
--- 2.4.4-mSsu/include/linux/shmem_fs.h	Wed May  2 18:36:05 2001
+++ 2.4.4-mSsua/include/linux/shmem_fs.h	Mon May  7 12:52:00 2001
@@ -17,6 +17,8 @@
 	unsigned long val;
 } swp_entry_t;
 
+extern atomic_t shmem_nrpages;
+
 struct shmem_inode_info {
 	spinlock_t		lock;
 	struct semaphore 	sem;
diff -uNr 2.4.4-mSsu/mm/mmap.c 2.4.4-mSsua/mm/mmap.c
--- 2.4.4-mSsu/mm/mmap.c	Sun Apr 29 20:33:01 2001
+++ 2.4.4-mSsua/mm/mmap.c	Mon May  7 13:42:03 2001
@@ -55,13 +55,24 @@
 	 */
 
 	long free;
-	
+	unsigned long cached, shmem;
+
+	/*
+	 * There may be some inconsistency because shmem_nrpages
+	 * update is delayed to the page_cache_size
+	 * We make sure the cached value does not get below zero 
+	 */
+	cached = atomic_read(&page_cache_size);
+	shmem  = atomic_read(&shmem_nrpages);
+	if (cached > shmem)
+		cached -= shmem;
+
         /* Sometimes we want to use more memory than we have. */
 	if (sysctl_overcommit_memory)
 	    return 1;
 
 	free = atomic_read(&buffermem_pages);
-	free += atomic_read(&page_cache_size);
+	free += cached;
 	free += nr_free_pages();
 	free += nr_swap_pages;
 
diff -uNr 2.4.4-mSsu/mm/shmem.c 2.4.4-mSsua/mm/shmem.c
--- 2.4.4-mSsu/mm/shmem.c	Fri May  4 21:37:34 2001
+++ 2.4.4-mSsua/mm/shmem.c	Mon May  7 11:13:27 2001
@@ -3,7 +3,8 @@
  *
  * Copyright (C) 2000 Linus Torvalds.
  *		 2000 Transmeta Corp.
- *		 2000 Christoph Rohland
+ *		 2000-2001 Christoph Rohland
+ *		 2000-2001 SAP AG
  * 
  * This file is released under the GPL.
  */
@@ -45,6 +46,7 @@
 
 LIST_HEAD (shmem_inodes);
 static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
+atomic_t shmem_nrpages = ATOMIC_INIT(0);
 
 #define BLOCKS_PER_PAGE (PAGE_SIZE/512)
 
@@ -52,6 +54,7 @@
  * shmem_recalc_inode - recalculate the size of an inode
  *
  * @inode: inode to recalc
+ * @swap:  additional swap pages freed externally
  *
  * We have to calculate the free blocks since the mm can drop pages
  * behind our back
@@ -62,12 +65,14 @@
  *
  * So the mm freed 
  * inodes->i_blocks/BLOCKS_PER_PAGE - 
- *			(inode->i_mapping->nrpages + info->swapped)
+ * 			(inode->i_mapping->nrpages + info->swapped)
  *
  * It has to be called with the spinlock held.
+ *
+ * The swap parameter is a performance hack for truncate.
  */
 
-static void shmem_recalc_inode(struct inode * inode)
+static void shmem_recalc_inode(struct inode * inode, unsigned long swap)
 {
 	unsigned long freed;
 
@@ -79,6 +84,7 @@
 		spin_lock (&info->stat_lock);
 		info->free_blocks += freed;
 		spin_unlock (&info->stat_lock);
+		atomic_sub(freed-swap, &shmem_nrpages);
 	}
 }
 
@@ -195,7 +201,7 @@
 out:
 	info->max_index = index;
 	info->swapped -= freed;
-	shmem_recalc_inode(inode);
+	shmem_recalc_inode(inode, freed);
 	spin_unlock (&info->lock);
 	up(&info->sem);
 }
@@ -250,14 +256,15 @@
 	entry = shmem_swp_entry(info, page->index);
 	if (IS_ERR(entry))	/* this had been allocted on page allocation */
 		BUG();
-	shmem_recalc_inode(page->mapping->host);
+	shmem_recalc_inode(page->mapping->host, 0);
 	error = -EAGAIN;
 	if (entry->val)
 		BUG();
 
 	*entry = swap;
 	error = 0;
-	/* Remove the from the page cache */
+	/* Remove the page from the page cache */
+	atomic_dec(&shmem_nrpages);
 	lru_cache_del(page);
 	remove_inode_page(page);
 
@@ -376,6 +383,7 @@
 	}
 
 	/* We have the page */
+	atomic_inc(&shmem_nrpages);
 	SetPageUptodate(page);
 	if (info->locked)
 		page_cache_get(page);
@@ -1275,6 +1283,7 @@
 	return 0;
 found:
 	add_to_page_cache(page, info->inode->i_mapping, offset + idx);
+	atomic_inc(&shmem_nrpages);
 	set_page_dirty(page);
 	SetPageUptodate(page);
 	UnlockPage(page);
diff -uNr 2.4.4-mSsu/arch/alpha/mm/init.c c/arch/alpha/mm/init.c
--- 2.4.4-mSsu/arch/alpha/mm/init.c	Sun Apr 29 20:31:56 2001
+++ c/arch/alpha/mm/init.c	Sun May  6 21:47:25 2001
@@ -402,7 +402,7 @@
 si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -uNr 2.4.4-mSsu/arch/arm/mm/init.c c/arch/arm/mm/init.c
--- 2.4.4-mSsu/arch/arm/mm/init.c	Sun Apr 29 20:31:56 2001
+++ c/arch/arm/mm/init.c	Sun May  6 21:47:01 2001
@@ -647,7 +647,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram  = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram   = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -uNr 2.4.4-mSsu/arch/cris/mm/init.c c/arch/cris/mm/init.c
--- 2.4.4-mSsu/arch/cris/mm/init.c	Sun Apr 29 20:31:57 2001
+++ c/arch/cris/mm/init.c	Sun May  6 21:47:03 2001
@@ -503,7 +503,7 @@
 
 	i = max_mapnr;
 	val->totalram = 0;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	while (i-- > 0)  {
diff -uNr 2.4.4-mSsu/arch/i386/mm/init.c c/arch/i386/mm/init.c
--- 2.4.4-mSsu/arch/i386/mm/init.c	Sun Apr 29 20:32:08 2001
+++ c/arch/i386/mm/init.c	Sun May  6 20:24:21 2001
@@ -570,7 +570,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = totalhigh_pages;
diff -uNr 2.4.4-mSsu/arch/ia64/mm/init.c c/arch/ia64/mm/init.c
--- 2.4.4-mSsu/arch/ia64/mm/init.c	Sun Apr 29 20:32:11 2001
+++ c/arch/ia64/mm/init.c	Sun May  6 21:47:05 2001
@@ -151,7 +151,7 @@
 si_meminfo (struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -uNr 2.4.4-mSsu/arch/m68k/mm/init.c c/arch/m68k/mm/init.c
--- 2.4.4-mSsu/arch/m68k/mm/init.c	Sat Nov  4 18:11:22 2000
+++ c/arch/m68k/mm/init.c	Sun May  6 21:47:45 2001
@@ -217,7 +217,7 @@
 
     i = max_mapnr;
     val->totalram = totalram_pages;
-    val->sharedram = 0;
+    val->sharedram = atomic_read(&shmem_nrpages);
     val->freeram = nr_free_pages();
     val->bufferram = atomic_read(&buffermem_pages);
     while (i-- > 0) {
diff -uNr 2.4.4-mSsu/arch/mips/mm/init.c c/arch/mips/mm/init.c
--- 2.4.4-mSsu/arch/mips/mm/init.c	Sat Nov  4 18:11:22 2000
+++ c/arch/mips/mm/init.c	Sun May  6 21:47:01 2001
@@ -343,7 +343,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -uNr 2.4.4-mSsu/arch/mips64/mm/init.c c/arch/mips64/mm/init.c
--- 2.4.4-mSsu/arch/mips64/mm/init.c	Sat Nov  4 18:11:22 2000
+++ c/arch/mips64/mm/init.c	Sun May  6 21:47:04 2001
@@ -411,7 +411,7 @@
 si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -uNr 2.4.4-mSsu/arch/parisc/mm/init.c c/arch/parisc/mm/init.c
--- 2.4.4-mSsu/arch/parisc/mm/init.c	Sun Dec 17 12:53:55 2000
+++ c/arch/parisc/mm/init.c	Sun May  6 21:47:02 2001
@@ -458,7 +458,7 @@
 
 	i = max_mapnr;
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 #if 0
diff -uNr 2.4.4-mSsu/arch/ppc/mm/init.c c/arch/ppc/mm/init.c
--- 2.4.4-mSsu/arch/ppc/mm/init.c	Wed Apr 11 12:36:13 2001
+++ c/arch/ppc/mm/init.c	Sun May  6 21:47:05 2001
@@ -336,7 +336,7 @@
 
 	i = max_mapnr;
 	val->totalram = 0;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	while (i-- > 0)  {
diff -uNr 2.4.4-mSsu/arch/s390/mm/init.c c/arch/s390/mm/init.c
--- 2.4.4-mSsu/arch/s390/mm/init.c	Sun Apr 29 20:32:21 2001
+++ c/arch/s390/mm/init.c	Sun May  6 21:47:03 2001
@@ -271,7 +271,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -uNr 2.4.4-mSsu/arch/s390x/mm/init.c c/arch/s390x/mm/init.c
--- 2.4.4-mSsu/arch/s390x/mm/init.c	Sun Apr 29 20:32:22 2001
+++ c/arch/s390x/mm/init.c	Sun May  6 21:47:18 2001
@@ -284,7 +284,7 @@
 void si_meminfo(struct sysinfo *val)
 {
         val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = 0;
diff -uNr 2.4.4-mSsu/arch/sh/mm/init.c c/arch/sh/mm/init.c
--- 2.4.4-mSsu/arch/sh/mm/init.c	Sun Apr 29 20:32:23 2001
+++ c/arch/sh/mm/init.c	Sun May  6 21:47:26 2001
@@ -215,7 +215,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = totalhigh_pages;
diff -uNr 2.4.4-mSsu/arch/sparc/mm/init.c c/arch/sparc/mm/init.c
--- 2.4.4-mSsu/arch/sparc/mm/init.c	Sun Apr 29 20:32:23 2001
+++ c/arch/sparc/mm/init.c	Sun May  6 21:47:04 2001
@@ -534,7 +534,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = totalram_pages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 	val->totalhigh = totalhigh_pages;
diff -uNr 2.4.4-mSsu/arch/sparc64/mm/init.c c/arch/sparc64/mm/init.c
--- 2.4.4-mSsu/arch/sparc64/mm/init.c	Sun Apr 29 20:32:25 2001
+++ c/arch/sparc64/mm/init.c	Sun May  6 21:47:02 2001
@@ -1512,7 +1512,7 @@
 void si_meminfo(struct sysinfo *val)
 {
 	val->totalram = num_physpages;
-	val->sharedram = 0;
+	val->sharedram = atomic_read(&shmem_nrpages);
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
 


             reply	other threads:[~2001-05-07 12:42 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-05-07 12:43 Christoph Rohland [this message]
2001-05-07 13:04 ` 2.4.4-ac5 aic7xxx causes hang on my machine Andy Carlson
2001-05-07 13:58   ` Oyvind Jagtnes
2001-05-07 14:14   ` Justin T. Gibbs

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m3y9s9nxcf.fsf@linux.local \
    --to=cr@sap.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).