linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: "Dr. Werner Fink" <werner@suse.de>
To: weule@marlene.neurologie.uni-duesseldorf.de
Cc: linux-kernel@vger.rutgers.edu, linux-mm@kvack.org
Subject: Re: shm and locked pages
Date: Mon, 1 Dec 1997 21:33:14 +0100	[thread overview]
Message-ID: <199712012033.VAA07814@boole.fs100.suse.de> (raw)
In-Reply-To: <199712010925.KAA09786@marlene.neurologie.uni-duesseldorf.de> (weule@marlene.neurologie.uni-duesseldorf.de)


> Hello Kernel-Developers!

Nice idea for stopping foolish syscalls like makeing hugh amount of
memory non-swappable.  But the calculation of your limits is not a win ...
please do not use floats within the kernel ;)

Nevertheless, the idea may explain and solve _some_ seen memory leaks due
locked but never unlocked shm's.

          Werner

> 
> If root is locking more shm pages to physical memory than the computer
> has, the system stopps running because all other pages are swapped out.
> To fix this, I patched ipc/shm.c and decided to limit the locked pages
> to
>         totalram - sqrt(totalram*8MB):
> 
>         /*
>          * Maximal locked shared memory:
>          *    totalmem - sqrt(8MB*totalram) if totalram > 8MB
>          *
>          * Exampes:
>          *
>          * totalram:     8 12.0 16.0 18 20.0 24.0 32 50 64.0 72 128 256
>          * never locked: 8  9.8 11.3 12 12.6 13.9 16 20 22.6 24  32  45
>          * max locked:   0  2.2  4.7  6  7.4 10.1 16 30 41.4 48  96 211
>          *
>          * The formular seem reasonable for me.
>          * t-sqrt(8MB*t)>m  <=3D=3D>  (t-m)*(t-m)-8MB*t>0
>          *
>          *                                  J"org Weule (weule@acm.org)
>          */
> 
> If a program locking half the pages hangs and a second one is started,
> the second will not lock the other half of the memory and the system is =
> still
> up. shm_lock.c is a program to test the number of pages one can lock.
> 
> The number val.totalram (struct sys_meminfo) may be replaced by =
> num_physpages
> at linux-2.1.xx in future releases.
> 
> Hope this helps
> 
> J"org
> -------------------------------------------------------------------------=
> ------
> J=F6rg Weule - weule@uni-duesseldorf.de - =
> http://www.cs.uni-duesseldorf.de/~weule
> --700c_66f6-60f5_4b48-54f0_ec4
> Content-Type: application/octet-stream; name=shm.c.diff-2.0.29
> Content-Transfer-Encoding: 7bit
> Content-MD5: IEgTrE1FgVh9D0rLd+A72Q==
> Content-Description: shm.c.diff-2.0.29
> Content-Disposition: attachment; filename=shm.c.diff-2.0.29
> 
> --- shm.c.orig	Fri Nov 28 15:43:41 1997
> +++ shm.c	Mon Dec  1 10:05:16 1997
> @@ -2,6 +2,7 @@
>   * linux/ipc/shm.c
>   * Copyright (C) 1992, 1993 Krishna Balasubramanian
>   *         Many improvements/fixes by Bruno Haible.
> + *         Limit of locked pages: J"org Weule (weule@acm.org), Nov 1997.
>   * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994.
>   */
>  
> @@ -28,6 +29,7 @@
>  static pte_t shm_swap_in(struct vm_area_struct *, unsigned long, unsigned long);
>  
>  static int shm_tot = 0; /* total number of shared memory pages */
> +static int shm_totlock = 0; /* total number of locked shared memory pages */
>  static int shm_rss = 0; /* number of shared memory pages that are in memory */
>  static int shm_swp = 0; /* number of shared memory pages that are in swap */
>  static int max_shmid = 0; /* every used id is <= max_shmid */
> @@ -47,7 +49,7 @@
>  
>  	for (id = 0; id < SHMMNI; id++)
>  		shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
> -	shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
> +	shm_tot = shm_totlock = shm_rss = shm_seq = max_shmid = used_segs = 0;
>  	shm_lock = NULL;
>  	return;
>  }
> @@ -191,6 +193,7 @@
>  			shm_swp--;
>  		}
>  	}
> +	if (shp->shm_perm.mode & SHM_LOCKED) shm_totlock -= numpages ;
>  	kfree(shp->shm_pages);
>  	shm_tot -= numpages;
>  	kfree(shp);
> @@ -289,6 +292,7 @@
>  		if (!(ipcp->mode & SHM_LOCKED))
>  			return -EINVAL;
>  		ipcp->mode &= ~SHM_LOCKED;
> +		shm_totlock -= shp->shm_npages;
>  		break;
>  	case SHM_LOCK:
>  /* Allow superuser to lock segment in memory */
> @@ -298,7 +302,31 @@
>  			return -EPERM;
>  		if (ipcp->mode & SHM_LOCKED)
>  			return -EINVAL;
> +		/*
> +		 * Maximal locked shared memory:
> +		 *    totalmem - sqrt(8MB*totalram) if totalram > 8MB
> +		 *
> +		 * Exampes:
> +		 *
> +		 * totalram:     8 12.0 16.0 18 20.0 24.0 32 50 64.0 72 128 256
> +		 * never locked: 8  9.8 11.3 12 12.6 13.9 16 20 22.6 24  32  45
> +		 * max locked:   0  2.2  4.7  6  7.4 10.1 16 30 41.4 48  96 211
> +		 *
> +		 * The formular seem reasonable for me.
> +		 * t-sqrt(8MB*t)>m  <==>  (t-m)*(t-m)-8MB*t>0
> +		 *
> +		 *                                  J"org Weule (weule@acm.org)
> +		 */
> +		{	struct sysinfo val ;
> +			double d ;
> +			si_meminfo(&val);
> +			d = ( shp->shm_npages + shm_totlock ) * PAGE_SIZE ;
> +			d -= val.totalram ;
> +			d = d * d / (1024UL*8192UL) - val.totalram ;
> +			if ( val.totalram < (8192UL*1024UL) || d < 0.0 ) return -EPERM ;
> +		}
>  		ipcp->mode |= SHM_LOCKED;
> +		shm_totlock += shp->shm_npages;
>  		break;
>  	case IPC_STAT:
>  		if (ipcperms (ipcp, S_IRUGO))
> --700c_66f6-60f5_4b48-54f0_ec4
> Content-Type: application/octet-stream; name=shm.c.diff-2.1.66
> Content-Transfer-Encoding: 7bit
> Content-MD5: qS9y3i3sA7ImutlYngf/iw==
> Content-Description: shm.c.diff-2.1.66
> Content-Disposition: attachment; filename=shm.c.diff-2.1.66
> 
> --- shm.c.orig	Mon Dec  1 09:34:44 1997
> +++ shm.c	Mon Dec  1 10:16:29 1997
> @@ -2,6 +2,7 @@
>   * linux/ipc/shm.c
>   * Copyright (C) 1992, 1993 Krishna Balasubramanian
>   *         Many improvements/fixes by Bruno Haible.
> + *         Limit of locked pages: J"org Weule (weule@acm.org), Nov 1997.
>   * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994.
>   */
>  
> @@ -32,6 +33,7 @@
>  static pte_t shm_swap_in(struct vm_area_struct *, unsigned long, unsigned long);
>  
>  static int shm_tot = 0; /* total number of shared memory pages */
> +static int shm_totlock = 0; /* total number of locked shared memory pages */
>  static int shm_rss = 0; /* number of shared memory pages that are in memory */
>  static int shm_swp = 0; /* number of shared memory pages that are in swap */
>  static int max_shmid = 0; /* every used id is <= max_shmid */
> @@ -51,7 +53,7 @@
>  
>  	for (id = 0; id < SHMMNI; id++)
>  		shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
> -	shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
> +	shm_tot = shm_totlock = shm_rss = shm_seq = max_shmid = used_segs = 0;
>  	shm_lock = NULL;
>  	return;
>  }
> @@ -201,6 +203,7 @@
>  			shm_swp--;
>  		}
>  	}
> +	if (shp->shm_perm.mode & SHM_LOCKED) shm_totlock -= numpages ;
>  	kfree(shp->shm_pages);
>  	shm_tot -= numpages;
>  	kfree(shp);
> @@ -312,6 +315,7 @@
>  		if (!(ipcp->mode & SHM_LOCKED))
>  			goto out;
>  		ipcp->mode &= ~SHM_LOCKED;
> +		shm_totlock -= shp->shm_npages;
>  		break;
>  	case SHM_LOCK:
>  /* Allow superuser to lock segment in memory */
> @@ -323,6 +327,31 @@
>  		err = -EINVAL;
>  		if (ipcp->mode & SHM_LOCKED)
>  			goto out;
> +		/*
> +		 * Maximal locked shared memory:
> +		 *    totalmem - sqrt(8MB*totalram) if totalram > 8MB
> +		 *
> +		 * Exampes:
> +		 *
> +		 * totalram:     8 12.0 16.0 18 20.0 24.0 32 50 64.0 72 128 256
> +		 * never locked: 8  9.8 11.3 12 12.6 13.9 16 20 22.6 24  32  45
> +		 * max locked:   0  2.2  4.7  6  7.4 10.1 16 30 41.4 48  96 211
> +		 *
> +		 * The formular seem reasonable for me.
> +		 * t-sqrt(8MB*t)>m  <==>  (t-m)*(t-m)-8MB*t>0
> +		 *
> +		 *                                  J"org Weule (weule@acm.org)
> +		 */
> +
> +		{	struct sysinfo val ;
> +			double d ;
> +			si_meminfo(&val);
> +			d = ( shp->shm_npages + shm_totlock ) * PAGE_SIZE ;
> +			d -= val.totalram ;
> +			d = d * d / (1024UL*8192UL) - val.totalram ;
> +			if ( val.totalram < (8192UL*1024UL) || d < 0.0 ) return -EPERM ;
> +		}
> +		shm_totlock += shp->shm_npages;
>  		ipcp->mode |= SHM_LOCKED;
>  		break;
>  	case IPC_STAT:
> --700c_66f6-60f5_4b48-54f0_ec4
> Content-Type: text/plain; charset=ISO-8859-1; name=shm_lock.c
> Content-Transfer-Encoding: 7bit
> Content-MD5: Bzn0f2BvObYZBLIoe8l3SQ==
> Content-Description: shm_lock.c
> Content-Disposition: attachment; filename=shm_lock.c
> X-Sun-Data-Type: c-file
> 
> #include <stdlib.h>
> #include <stdio.h>
> #include <sys/types.h>
> #include <sys/ipc.h>
> #include <sys/shm.h>
> #include <sys/wait.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> 
> /*
>  * Tries to lock 200 MB of memory and sleeps the number of seconds
>  * specified by the first parameter. root can test shm with this program.
>  * (C)opyright by J"org Weule (weule@acm.org), Nov 1997.
>  */
> 
> int s[100];
> char*(p[100]);
> 
> int main(int argc,char*argv[]){
> 	int f ;
> 	int pid , st ;
> 	int i , tot = 0 ;
> 	key_t k = IPC_PRIVATE ;
> 	int n = 1024*1024*2 ;
> 	do {
> 		s[0]=shmget(k, n, (int)IPC_CREAT|0600);
> 		if ( s[0] < 0 ) n -= 1024 ;
> 		else break ;
> 	} while( n>1024 );
> 	if ( s[0] < 0 ) printf("shmget->%d\n",s[0]),perror("shmget"),exit(1);
> 	tot += n ;
> 	p[0]=shmat(s[0],NULL,0);
> 	if(0>=shmctl(s[0],IPC_RMID,NULL))puts("RMID 1");
> 	if ( shmctl(s[0],SHM_LOCK,NULL)>=0) puts("lock1");
> 	printf("%d\n",n);
> 	for ( i = 1 ; i < 100 ; i++ ){
> 		s[i]=shmget(k, n, (int)IPC_CREAT|0600);
> 		if ( s[i] < 0 ) printf("shmget->%d\n",s[i]),perror("shmget"),exit(1);
> 		p[i]=shmat(s[i],NULL,0);
> 		if(0>=shmctl(s[i],IPC_RMID,NULL))puts("RMID 1");
> 		if ( shmctl(s[i],SHM_LOCK,NULL)>=0) puts("lock1");
> 		else break ;
> 		tot += n ;
> 		printf("%20d\n",tot);
> 	}
> 	if ( argc > 1 ) sleep(atoi(argv[1]));
> 	else system("ipcs -m"),sleep(60);
> 	exit(0);
> } 
>  
> 
> --700c_66f6-60f5_4b48-54f0_ec4--
> 

           reply	other threads:[~1997-12-01 20:39 UTC|newest]

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <199712010925.KAA09786@marlene.neurologie.uni-duesseldorf.de>]

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=199712012033.VAA07814@boole.fs100.suse.de \
    --to=werner@suse.de \
    --cc=linux-kernel@vger.rutgers.edu \
    --cc=linux-mm@kvack.org \
    --cc=weule@marlene.neurologie.uni-duesseldorf.de \
    /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