Messages in this thread Patch in this message | | | Subject | [Patch] shm bug introduced with pagecache in 2.3.11 | From | Christoph Rohland <> | Date | 11 Nov 1999 16:43:08 +0100 |
| |
Hi Linus,
Finally shm swapping seems to work for me again. The following patch fixes a refcounting bug which got introduced with 2.3.11. (Thanks to Manfred who finally found the right point). It survived a lot of swap stress testing on UP/32MB up to 8xSMP/8GB.
The patch also fixes some int/size_t issues.
Could you please apply this.
Greetings Christoph
--- 2.3.27-pre6/ipc/shm.c Thu Nov 11 10:33:16 1999 +++ make27/ipc/shm.c Thu Nov 11 14:47:57 1999 @@ -206,7 +206,7 @@ struct shmid_kernel *shp; int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT; int id, err; - unsigned int shmall, shmmni; + size_t shmall, shmmni; shmall = shm_prm[1]; shmmni = shm_prm[2]; @@ -378,13 +378,16 @@ case IPC_INFO: { struct shminfo shminfo; + size_t shmmax; + spin_unlock(&shm_lock); err = -EFAULT; if (!buf) goto out; + shmmax=shm_prm[0]; + shminfo.shmmax = shmmax > UINT_MAX ? UINT_MAX : shmmax; shminfo.shmmni = shminfo.shmseg = shm_prm[2]; - shminfo.shmmax = shm_prm[0]; shminfo.shmall = shm_prm[1]; shminfo.shmmin = SHMMIN; @@ -791,11 +794,14 @@ if (!page) { lock_kernel(); swapin_readahead(entry); + if (pte_val(pte) != pte_val(SHM_ENTRY(shp, idx))) goto again; page = read_swap_cache(entry); unlock_kernel(); if (!page) goto oom; } + if (pte_val(pte) != pte_val(SHM_ENTRY(shp, idx))) + goto changed; delete_from_swap_cache(page); page = replace_with_highmem(page); lock_kernel(); @@ -803,9 +809,6 @@ unlock_kernel(); spin_lock(&shm_lock); shm_swp--; - pte = SHM_ENTRY(shp, idx); - if (pte_present(pte)) - goto present; } shm_rss++; pte = pte_mkdirty(mk_pte(page, PAGE_SHARED)); @@ -813,8 +816,6 @@ } else --current->maj_flt; /* was incremented in do_no_page */ -done: - /* pte_val(pte) == SHM_ENTRY (shp, idx) */ get_page(pte_page(pte)); spin_unlock(&shm_lock); current->min_flt++; @@ -823,10 +824,6 @@ changed: __free_page(page); goto again; -present: - if (page) - free_page_and_swap_cache(page); - goto done; oom: return NOPAGE_OOM; }
| |