[Patch] avoid vmalloc in shm.c and some cleanups

Christoph Rohland (hans-christoph.rohland@sap.com)
20 Oct 1999 14:43:28 +0200


--Multipart_Wed_Oct_20_14:43:28_1999-1
Content-Type: text/plain; charset=US-ASCII

Hi,

During some investigations on posix shared memory I discovered that
the use of vmalloc in shm.c can cause oom when using lots of big shm
segments.

The following patch fixes this and cleans up sys_ipc. It also removes
some bogus comments in shmparam.h and adds shmall to be tuneable.

I would also like to have SHMMNI tuneable. But this means fiddling
with the _SHM_ID_BITS which pose a fixed limit on this. Also SHMMAX is
limited by this parameter.

I would suggest the following:
- Set _SHM_ID_BITS to 13 (which means up to 8192 shm segments possible
totally and shmmax up to 2GB)
- Set SHMMNI to 128 by default and check on resize against
(1<<_SHM_ID_BITS)
- Put a check in tuneing shmmax against (1<<(32-_SHM_ID_BITS)
- Also shmall should be probably checked against available physical
memory w/o BIGMEM

and put all these parameters together in /proc/sys/vm/sysvshm.

Any comments?
Christoph

--Multipart_Wed_Oct_20_14:43:28_1999-1
Content-Type: text/plain; charset=US-ASCII
Content-Disposition: attachment; filename="patch-shm1"
Content-Transfer-Encoding: 7bit

diff -ruN 2.3.22/arch/i386/kernel/sys_i386.c 2.3.22-cr1c/arch/i386/kernel/sys_i386.c
--- 2.3.22/arch/i386/kernel/sys_i386.c Fri Dec 18 01:27:35 1998
+++ 2.3.22-cr1c/arch/i386/kernel/sys_i386.c Wed Oct 20 13:28:48 1999
@@ -116,86 +116,71 @@
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;

- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- return sys_semop (first, (struct sembuf *)ptr, second);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
- default:
- return -EINVAL;
- }
+ switch (call) {
+ case SEMOP:
+ return sys_semop (first, (struct sembuf *)ptr, second);
+ case SEMGET:
+ return sys_semget (first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ if (!ptr)
+ return -EINVAL;
+ if (get_user(fourth.__pad, (void **) ptr))
+ return -EFAULT;
+ return sys_semctl (first, second, third, fourth);
+ }

- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds *) ptr);
- default:
- return -EINVAL;
- }
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = sys_shmat (first, (char *) ptr,
- second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return sys_shmat (first, (char *) ptr,
- second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
- default:
- return -EINVAL;
- }
-
- return -EINVAL;
+ case MSGSND:
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
+ if (!ptr)
+ return -EINVAL;
+
+ if (copy_from_user(&tmp,
+ (struct ipc_kludge *) ptr,
+ sizeof (tmp)))
+ return -EFAULT;
+ return sys_msgrcv (first, tmp.msgp, second,
+ tmp.msgtyp, third);
+ }
+ default:
+ return sys_msgrcv (first,
+ (struct msgbuf *) ptr,
+ second, fifth, third);
+ }
+ case MSGGET:
+ return sys_msgget ((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+ case SHMAT:
+ switch (version) {
+ default: {
+ ulong raddr;
+ ret = sys_shmat (first, (char *) ptr, second, &raddr);
+ if (ret)
+ return ret;
+ return put_user (raddr, (ulong *) third);
+ }
+ case 1: /* iBCS2 emulator entry point */
+ if (!segment_eq(get_fs(), get_ds()))
+ return -EINVAL;
+ return sys_shmat (first, (char *) ptr, second, (ulong *) third);
+ }
+ case SHMDT:
+ return sys_shmdt ((char *)ptr);
+ case SHMGET:
+ return sys_shmget (first, second, third);
+ case SHMCTL:
+ return sys_shmctl (first, second,
+ (struct shmid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
}

/*
diff -ruN 2.3.22/include/asm-alpha/shmparam.h 2.3.22-cr1c/include/asm-alpha/shmparam.h
--- 2.3.22/include/asm-alpha/shmparam.h Mon Oct 7 14:12:29 1996
+++ 2.3.22-cr1c/include/asm-alpha/shmparam.h Wed Oct 20 13:34:33 1999
@@ -31,11 +31,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the Alpha and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMAX 0x3fa000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
diff -ruN 2.3.22/include/asm-arm/shmparam.h 2.3.22-cr1c/include/asm-arm/shmparam.h
--- 2.3.22/include/asm-arm/shmparam.h Wed Jan 21 01:39:43 1998
+++ 2.3.22-cr1c/include/asm-arm/shmparam.h Wed Oct 20 13:34:10 1999
@@ -32,11 +32,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
#define SHMALL /* max shm system wide (pages) */ \
diff -ruN 2.3.22/include/asm-i386/shmparam.h 2.3.22-cr1c/include/asm-i386/shmparam.h
--- 2.3.22/include/asm-i386/shmparam.h Sun Nov 8 23:06:18 1998
+++ 2.3.22-cr1c/include/asm-i386/shmparam.h Wed Oct 20 13:33:06 1999
@@ -21,17 +21,12 @@
* Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
* there is a static array of size SHMMNI.
*/
#define _SHM_ID_BITS 7
#define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1)

#define SHM_IDX_SHIFT (_SHM_ID_BITS)
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */

#define SHMMAX 0x2000000 /* max shared seg size (bytes) */
/* Try not to change the default shipped SHMMAX - people rely on it */
diff -ruN 2.3.22/include/asm-m68k/shmparam.h 2.3.22-cr1c/include/asm-m68k/shmparam.h
--- 2.3.22/include/asm-m68k/shmparam.h Mon Oct 18 14:35:02 1999
+++ 2.3.22-cr1c/include/asm-m68k/shmparam.h Wed Oct 20 13:32:56 1999
@@ -33,11 +33,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMAX 0x1000000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
diff -ruN 2.3.22/include/asm-mips/shmparam.h 2.3.22-cr1c/include/asm-mips/shmparam.h
--- 2.3.22/include/asm-mips/shmparam.h Sat Jun 26 02:37:53 1999
+++ 2.3.22-cr1c/include/asm-mips/shmparam.h Wed Oct 20 13:32:29 1999
@@ -28,11 +28,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMAX 0x2000000 /* max shared seg size (bytes) */
/* Try not to change the default shipped SHMMAX - people rely on it */

diff -ruN 2.3.22/include/asm-ppc/shmparam.h 2.3.22-cr1c/include/asm-ppc/shmparam.h
--- 2.3.22/include/asm-ppc/shmparam.h Mon Oct 18 14:35:24 1999
+++ 2.3.22-cr1c/include/asm-ppc/shmparam.h Wed Oct 20 13:32:22 1999
@@ -28,11 +28,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMAX 0x2000000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
diff -ruN 2.3.22/include/asm-sh/shmparam.h 2.3.22-cr1c/include/asm-sh/shmparam.h
--- 2.3.22/include/asm-sh/shmparam.h Mon Oct 18 14:34:54 1999
+++ 2.3.22-cr1c/include/asm-sh/shmparam.h Wed Oct 20 13:32:06 1999
@@ -28,11 +28,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMAX 0x2000000 /* max shared seg size (bytes) */
/* Try not to change the default shipped SHMMAX - people rely on it */

diff -ruN 2.3.22/include/asm-sparc/shmparam.h 2.3.22-cr1c/include/asm-sparc/shmparam.h
--- 2.3.22/include/asm-sparc/shmparam.h Sun Oct 4 19:22:44 1998
+++ 2.3.22-cr1c/include/asm-sparc/shmparam.h Wed Oct 20 13:31:52 1999
@@ -29,11 +29,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMAX 0x1000000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
diff -ruN 2.3.22/include/asm-sparc64/shmparam.h 2.3.22-cr1c/include/asm-sparc64/shmparam.h
--- 2.3.22/include/asm-sparc64/shmparam.h Sun Oct 4 19:22:44 1998
+++ 2.3.22-cr1c/include/asm-sparc64/shmparam.h Wed Oct 20 13:31:41 1999
@@ -31,11 +31,6 @@
#define _SHM_IDX_BITS 15
#define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1)

-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
#define SHMMAX 0x1000000 /* max shared seg size (bytes) */
#define SHMMIN 1 /* really PAGE_SIZE */ /* min shared seg size (bytes) */
#define SHMMNI (1<<_SHM_ID_BITS) /* max num of segs system wide */
diff -ruN 2.3.22/include/linux/shm.h 2.3.22-cr1c/include/linux/shm.h
--- 2.3.22/include/linux/shm.h Mon Oct 18 14:34:45 1999
+++ 2.3.22-cr1c/include/linux/shm.h Wed Oct 20 13:36:57 1999
@@ -24,7 +24,7 @@
struct shmid_ds u;
/* the following are private */
unsigned long shm_npages; /* size of segment (pages) */
- unsigned long *shm_pages; /* array of ptrs to frames -> SHMMAX */
+ unsigned long **shm_dir; /* array of ptrs to ptrs to frames -> SHMMAX */
struct vm_area_struct *attaches; /* descriptors for attaches */
};

diff -ruN 2.3.22/include/linux/sysctl.h 2.3.22-cr1c/include/linux/sysctl.h
--- 2.3.22/include/linux/sysctl.h Mon Oct 18 14:35:08 1999
+++ 2.3.22-cr1c/include/linux/sysctl.h Wed Oct 20 13:28:48 1999
@@ -103,7 +103,8 @@
KERN_MSGPOOL=37, /* int: Maximum system message pool size */
KERN_SYSRQ=38, /* int: Sysreq enable */
KERN_MAX_THREADS=39, /* int: Maximum nr of threads in the system */
- KERN_RANDOM=40 /* Random driver */
+ KERN_RANDOM=40, /* Random driver */
+ KERN_SHMALL=41 /* int: Maximum shared memory total */
};


diff -ruN 2.3.22/ipc/shm.c 2.3.22-cr1c/ipc/shm.c
--- 2.3.22/ipc/shm.c Mon Oct 18 14:35:24 1999
+++ 2.3.22-cr1c/ipc/shm.c Wed Oct 20 13:40:28 1999
@@ -38,6 +38,9 @@
static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
#endif

+unsigned int shmmax = SHMMAX;
+unsigned int shmall = SHMALL;
+
static int shm_tot = 0; /* total number of 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 */
@@ -72,6 +75,58 @@
return;
}

+#define SHM_ENTRY(shp, index) (shp)->shm_dir[(index)/PTRS_PER_PTE][(index)%PTRS_PER_PTE]
+
+static unsigned long **shm_alloc(unsigned long pages)
+{
+ unsigned short dir = pages / PTRS_PER_PTE;
+ unsigned short last = pages % PTRS_PER_PTE;
+ unsigned long **ret, **ptr;
+
+ ret = kmalloc ((dir+1) * sizeof(unsigned long), GFP_KERNEL);
+ if (ret == NULL)
+ return NULL;
+
+ for (ptr = ret; ptr < ret+dir ; ptr++)
+ {
+ *ptr = (unsigned long *)__get_free_page (GFP_KERNEL);
+ if (*ptr == NULL)
+ goto free;
+ }
+
+ /* The last one is probably not of PAGE_SIZE: we use kmalloc */
+ if (last) {
+ *ptr = kmalloc (last*sizeof(unsigned long), GFP_KERNEL);
+ if (*ptr == NULL)
+ goto free;
+ }
+ return ret;
+
+free:
+ /* The last failed: we decrement first */
+ while (--ptr >= ret)
+ free_page ((unsigned long)*ptr);
+
+ kfree (ret);
+ return NULL;
+}
+
+
+static void shm_free(unsigned long** dir, unsigned long pages)
+{
+ unsigned long **ptr = dir+pages/PTRS_PER_PTE;
+
+ /* first the last page */
+ if (pages%PTRS_PER_PTE)
+ kfree (*ptr);
+ /* now the whole pages */
+ while (--ptr >= dir)
+ free_page ((unsigned long)*ptr);
+
+ /* Now the indirect block */
+ kfree (dir);
+}
+
static int findkey (key_t key)
{
int id;
@@ -112,7 +167,7 @@

if (size < SHMMIN)
return -EINVAL;
- if (shm_tot + numpages >= SHMALL)
+ if (shm_tot + numpages >= shmall)
return -ENOSPC;
for (id = 0; id < SHMMNI; id++)
if (shm_segs[id] == IPC_UNUSED) {
@@ -130,18 +185,16 @@
wake_up (&shm_wait);
return -ENOMEM;
}
- lock_kernel();
- shp->shm_pages = (ulong *) vmalloc (numpages*sizeof(ulong));
- unlock_kernel();
- if (!shp->shm_pages) {
- kfree(shp);
+ shp->shm_dir = shm_alloc (numpages);
+ if (!shp->shm_dir) {
spin_lock(&shm_lock);
shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
wake_up (&shm_wait);
return -ENOMEM;
}

- for (i = 0; i < numpages; shp->shm_pages[i++] = 0);
+ for (i = 0; i < numpages; i++)
+ SHM_ENTRY(shp,i) = 0;
shp->u.shm_perm.key = key;
shp->u.shm_perm.mode = (shmflg & S_IRWXUGO);
shp->u.shm_perm.cuid = shp->u.shm_perm.uid = current->euid;
@@ -167,8 +220,6 @@
return (unsigned int) shp->u.shm_perm.seq * SHMMNI + id;
}

-int shmmax = SHMMAX;
-
asmlinkage long sys_shmget (key_t key, int size, int shmflg)
{
struct shmid_kernel *shp;
@@ -224,15 +275,15 @@
used_segs--;
if (id == max_shmid)
while (max_shmid && (shm_segs[--max_shmid] == IPC_UNUSED));
- if (!shp->shm_pages) {
- printk ("shm nono: killseg shp->pages=NULL. id=%d\n", id);
+ if (!shp->shm_dir) {
+ printk ("shm nono: killseg shp->shm_dir=NULL. id=%d\n", id);
return;
}
spin_unlock(&shm_lock);
numpages = shp->shm_npages;
for (i = 0, rss = 0, swp = 0; i < numpages ; i++) {
pte_t pte;
- pte = __pte(shp->shm_pages[i]);
+ pte = __pte(SHM_ENTRY (shp,i));
if (pte_none(pte))
continue;
if (pte_present(pte)) {
@@ -245,9 +296,7 @@
swp++;
}
}
- lock_kernel();
- vfree(shp->shm_pages);
- unlock_kernel();
+ shm_free (shp->shm_dir, numpages);
kfree(shp);
spin_lock(&shm_lock);
shm_rss -= rss;
@@ -282,7 +331,7 @@
shminfo.shmmni = SHMMNI;
shminfo.shmmax = shmmax;
shminfo.shmmin = SHMMIN;
- shminfo.shmall = SHMALL;
+ shminfo.shmall = shmall;
shminfo.shmseg = SHMSEG;
spin_unlock(&shm_lock);
if(copy_to_user (buf, &shminfo, sizeof(struct shminfo)))
@@ -482,16 +531,12 @@

down(&current->mm->mmap_sem);
spin_lock(&shm_lock);
- if (shmid < 0) {
- /* printk("shmat() -> EINVAL because shmid = %d < 0\n",shmid); */
+ if (shmid < 0)
goto out;
- }

shp = shm_segs[id = (unsigned int) shmid % SHMMNI];
- if (shp == IPC_UNUSED || shp == IPC_NOID) {
- /* printk("shmat() -> EINVAL because shmid = %d is invalid\n",shmid); */
+ if (shp == IPC_UNUSED || shp == IPC_NOID)
goto out;
- }

if (!(addr = (ulong) shmaddr)) {
if (shmflg & SHM_REMAP)
@@ -664,7 +709,7 @@
}

/*
- * page not present ... go through shm_pages
+ * page not present ... go through shm_dir
*/
static unsigned long shm_nopage(struct vm_area_struct * shmd, unsigned long address, int no_share)
{
@@ -673,6 +718,7 @@
unsigned int idx;
unsigned long page;
struct page * page_map;
+ unsigned long ret = 0;

shp = *(struct shmid_kernel **) shmd->vm_private_data;
idx = (address - shmd->vm_start + shmd->vm_offset) >> PAGE_SHIFT;
@@ -688,9 +734,8 @@
}
#endif

- spin_lock(&shm_lock);
- again:
- pte = __pte(shp->shm_pages[idx]);
+again:
+ pte = __pte(SHM_ENTRY(shp,idx));
if (!pte_present(pte)) {
if (pte_none(pte)) {
spin_unlock(&shm_lock);
@@ -699,7 +744,7 @@
goto oom;
clear_bigpage(page);
spin_lock(&shm_lock);
- if (pte_val(pte) != shp->shm_pages[idx])
+ if (pte_val(pte) != SHM_ENTRY(shp, idx))
goto changed;
} else {
unsigned long entry = pte_val(pte);
@@ -722,17 +767,17 @@
unlock_kernel();
spin_lock(&shm_lock);
shm_swp--;
- pte = __pte(shp->shm_pages[idx]);
+ pte = __pte(SHM_ENTRY(shp, idx));
if (pte_present(pte))
goto present;
}
shm_rss++;
pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
- shp->shm_pages[idx] = pte_val(pte);
+ SHM_ENTRY(shp, idx) = pte_val(pte);
} else
--current->maj_flt; /* was incremented in do_no_page */

-done: /* pte_val(pte) == shp->shm_pages[idx] */
+done: /* pte_val(pte) == SHM_ENTRY (shp, idx) */
get_page(mem_map + MAP_NR(pte_page(pte)));
spin_unlock(&shm_lock);
current->min_flt++;
@@ -744,6 +789,7 @@
present:
free_page(page);
goto done;
+
oom:
return -1;
}
@@ -793,7 +839,7 @@
if (idx >= shp->shm_npages)
goto next_id;

- page = __pte(shp->shm_pages[idx]);
+ page = __pte(SHM_ENTRY(shp, idx));
if (!pte_present(page))
goto check_table;
page_map = &mem_map[MAP_NR(pte_page(page))];
@@ -815,7 +861,7 @@
goto check_table;
if (!(page_map = prepare_bigmem_swapout(page_map)))
goto check_table;
- shp->shm_pages[idx] = swap_nr;
+ SHM_ENTRY(shp, idx) = swap_nr;
swap_successes++;
shm_swp++;
shm_rss--;
@@ -839,7 +885,7 @@
pte_t pte;

pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
- shp->shm_pages[idx] = pte_val(pte);
+ SHM_ENTRY(shp, idx) = pte_val(pte);
get_page(mem_map + MAP_NR(page));
shm_rss++;

@@ -862,7 +908,7 @@
for (i = 0; i < SHMMNI; i++)
if (shm_segs[i] != IPC_UNUSED && shm_segs[i] != IPC_NOID)
for (n = 0; n < shm_segs[i]->shm_npages; n++)
- if (shm_segs[i]->shm_pages[n] == entry)
+ if (SHM_ENTRY(shm_segs[i], n) == entry)
{
shm_unuse_page(shm_segs[i], n,
page, entry);
diff -ruN 2.3.22/kernel/sysctl.c 2.3.22-cr1c/kernel/sysctl.c
--- 2.3.22/kernel/sysctl.c Mon Oct 18 14:35:24 1999
+++ 2.3.22-cr1c/kernel/sysctl.c Wed Oct 20 13:28:48 1999
@@ -49,7 +49,8 @@
extern int sg_big_buff;
#endif
#ifdef CONFIG_SYSVIPC
-extern int shmmax;
+extern unsigned int shmmax;
+extern unsigned int shmall;
#endif

#ifdef __sparc__
@@ -213,7 +214,9 @@
{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
0644, NULL, &proc_dointvec},
#ifdef CONFIG_SYSVIPC
- {KERN_SHMMAX, "shmmax", &shmmax, sizeof (int),
+ {KERN_SHMMAX, "shmmax", &shmmax, sizeof (unsigned int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_SHMALL, "shmall", &shmall, sizeof (unsigned int),
0644, NULL, &proc_dointvec},
#endif
#ifdef CONFIG_MAGIC_SYSRQ

--Multipart_Wed_Oct_20_14:43:28_1999-1--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/