patch-2.3.25 linux/ipc/shm.c
Next file: linux/ipc/util.c
Previous file: linux/ipc/sem.c
Back to the patch index
Back to the overall index
- Lines: 214
- Date:
Fri Oct 29 15:07:16 1999
- Orig file:
v2.3.24/linux/ipc/shm.c
- Orig date:
Wed Oct 27 16:34:12 1999
diff -u --recursive --new-file v2.3.24/linux/ipc/shm.c linux/ipc/shm.c
@@ -27,7 +27,7 @@
extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
static int findkey (key_t key);
-static int newseg (key_t key, int shmflg, int size);
+static int newseg (key_t key, int shmflg, size_t size);
static int shm_map (struct vm_area_struct *shmd);
static void killseg (int id);
static void shm_open (struct vm_area_struct *shmd);
@@ -57,17 +57,13 @@
void __init shm_init (void)
{
int id;
-#ifdef CONFIG_PROC_FS
- struct proc_dir_entry *ent;
-#endif
for (id = 0; id < SHMMNI; id++)
shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
init_waitqueue_head(&shm_wait);
#ifdef CONFIG_PROC_FS
- ent = create_proc_entry("sysvipc/shm", 0, 0);
- ent->read_proc = sysvipc_shm_read_proc;
+ create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc, NULL);
#endif
return;
}
@@ -104,7 +100,7 @@
/*
* allocate new shmid_kernel and pgtable. protected by shm_segs[id] = NOID.
*/
-static int newseg (key_t key, int shmflg, int size)
+static int newseg (key_t key, int shmflg, size_t size)
{
struct shmid_kernel *shp;
int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
@@ -168,16 +164,16 @@
return (unsigned int) shp->u.shm_perm.seq * SHMMNI + id;
}
-int shmmax = SHMMAX;
+size_t shmmax = SHMMAX;
-asmlinkage long sys_shmget (key_t key, int size, int shmflg)
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
{
struct shmid_kernel *shp;
int err, id = 0;
down(¤t->mm->mmap_sem);
spin_lock(&shm_lock);
- if (size < 0 || size > shmmax) {
+ if (size > shmmax) {
err = -EINVAL;
} else if (key == IPC_PRIVATE) {
err = newseg(key, shmflg, size);
@@ -237,7 +233,7 @@
rss++;
} else {
lock_kernel();
- swap_free(pte);
+ swap_free(pte_to_swp_entry(pte));
unlock_kernel();
swp++;
}
@@ -409,7 +405,7 @@
* shmd->vm_end multiple of SHMLBA
* shmd->vm_next next attach for task
* shmd->vm_next_share next attach for segment
- * shmd->vm_offset offset into segment
+ * shmd->vm_pgoff offset into segment (in pages)
* shmd->vm_private_data signature for this attach
*/
@@ -494,7 +490,7 @@
err = -ENOMEM;
addr = 0;
again:
- if (!(addr = get_unmapped_area(addr, shp->u.shm_segsz)))
+ if (!(addr = get_unmapped_area(addr, (unsigned long)shp->u.shm_segsz)))
goto out;
if(addr & (SHMLBA - 1)) {
addr = (addr + (SHMLBA - 1)) & ~(SHMLBA - 1);
@@ -520,7 +516,7 @@
if (addr < current->mm->start_stack &&
addr > current->mm->start_stack - PAGE_SIZE*(shp->shm_npages + 4))
goto out;
- if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + shp->u.shm_segsz))
+ if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + (unsigned long)shp->u.shm_segsz))
goto out;
err = -EACCES;
@@ -551,7 +547,7 @@
| VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC
| ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE);
shmd->vm_file = NULL;
- shmd->vm_offset = 0;
+ shmd->vm_pgoff = 0;
shmd->vm_ops = &shm_vm_ops;
shp->u.shm_nattch++; /* prevent destruction */
@@ -631,7 +627,7 @@
for (shmd = current->mm->mmap; shmd; shmd = shmdnext) {
shmdnext = shmd->vm_next;
if (shmd->vm_ops == &shm_vm_ops
- && shmd->vm_start - shmd->vm_offset == (ulong) shmaddr)
+ && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr)
do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
}
up(¤t->mm->mmap_sem);
@@ -662,7 +658,8 @@
struct page * page;
shp = *(struct shmid_kernel **) shmd->vm_private_data;
- idx = (address - shmd->vm_start + shmd->vm_offset) >> PAGE_SHIFT;
+ idx = (address - shmd->vm_start) >> PAGE_SHIFT;
+ idx += shmd->vm_pgoff;
spin_lock(&shm_lock);
again:
@@ -678,7 +675,7 @@
if (pte_val(pte) != pte_val(shp->shm_pages[idx]))
goto changed;
} else {
- pte_t entry = pte;
+ swp_entry_t entry = pte_to_swp_entry(pte);
spin_unlock(&shm_lock);
page = lookup_swap_cache(entry);
@@ -735,15 +732,18 @@
{
pte_t page;
struct shmid_kernel *shp;
- pte_t swap_entry;
+ swp_entry_t swap_entry;
unsigned long id, idx;
int loop = 0;
int counter;
struct page * page_map;
counter = shm_rss >> prio;
+ if (!counter)
+ return 0;
lock_kernel();
- if (!counter || !pte_val(swap_entry = get_swap_page())) {
+ swap_entry = get_swap_page();
+ if (!swap_entry.val) {
unlock_kernel();
return 0;
}
@@ -792,7 +792,7 @@
goto check_table;
if (!(page_map = prepare_highmem_swapout(page_map)))
goto check_table;
- shp->shm_pages[idx] = swap_entry;
+ shp->shm_pages[idx] = swp_entry_to_pte(swap_entry);
swap_successes++;
shm_swp++;
shm_rss--;
@@ -812,7 +812,7 @@
* Free the swap entry and set the new pte for the shm page.
*/
static void shm_unuse_page(struct shmid_kernel *shp, unsigned long idx,
- pte_t entry, struct page *page)
+ swp_entry_t entry, struct page *page)
{
pte_t pte;
@@ -832,7 +832,7 @@
/*
* unuse_shm() search for an eventually swapped out shm page.
*/
-void shm_unuse(pte_t entry, struct page *page)
+void shm_unuse(swp_entry_t entry, struct page *page)
{
int i, n;
@@ -841,11 +841,16 @@
struct shmid_kernel *seg = shm_segs[i];
if ((seg == IPC_UNUSED) || (seg == IPC_NOID))
continue;
- for (n = 0; n < seg->shm_npages; n++)
- if (pte_val(seg->shm_pages[n]) == pte_val(entry)) {
+ for (n = 0; n < seg->shm_npages; n++) {
+ if (pte_none(seg->shm_pages[n]))
+ continue;
+ if (pte_present(seg->shm_pages[n]))
+ continue;
+ if (pte_to_swp_entry(seg->shm_pages[n]).val == entry.val) {
shm_unuse_page(seg, n, entry, page);
return;
}
+ }
}
spin_unlock(&shm_lock);
}
@@ -862,7 +867,15 @@
spin_lock(&shm_lock);
for(i = 0; i < SHMMNI; i++)
if(shm_segs[i] != IPC_UNUSED) {
- len += sprintf(buffer + len, "%10d %10d %4o %10d %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n",
+#define SMALL_STRING "%10d %10d %4o %10u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
+#define BIG_STRING "%10d %10d %4o %21u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
+ char *format;
+
+ if (sizeof(size_t) <= sizeof(int))
+ format = SMALL_STRING;
+ else
+ format = BIG_STRING;
+ len += sprintf(buffer + len, format,
shm_segs[i]->u.shm_perm.key,
shm_segs[i]->u.shm_perm.seq * SHMMNI + i,
shm_segs[i]->u.shm_perm.mode,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)