From: ebiederm+eric@npwt.net (Eric W. Biederman)
To: "Stephen C. Tweedie" <sct@dcs.ed.ac.uk>
Cc: linux-mm@kvack.org
Subject: Re: patch for 2.1.102 swap code
Date: 11 Jun 1998 09:31:22 -0500 [thread overview]
Message-ID: <m167i857t1.fsf@flinx.npwt.net> (raw)
In-Reply-To: "Stephen C. Tweedie"'s message of Tue, 26 May 1998 22:52:21 +0100
>>>>> "ST" == Stephen C Tweedie <sct@dcs.ed.ac.uk> writes:
ST> Hi,
>> Note: there is a problem with swapoff that should at least be considered.
>> If you use have a SYSV shared memory, and don't map it into a process,
>> and that memory get's swapped out, swapoff will not be able to find it.
>> This is a very long standing bug and appears not to be a problem in practice.
>> But it is certainly a potential problem.
ST> Thanks; it's added to my list.
Here is a preliminary patch that should fix the problem.
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.1.101.x0/include/linux/swap.h linux-2.1.101.x2/include/linux/swap.h
--- linux-2.1.101.x0/include/linux/swap.h Wed Apr 22 11:08:16 1998
+++ linux-2.1.101.x2/include/linux/swap.h Wed Jun 3 22:21:51 1998
@@ -75,7 +75,18 @@
void si_swapinfo(struct sysinfo *);
unsigned long get_swap_page(void);
extern void FASTCALL(swap_free(unsigned long));
+
+ /* So that external drivers can use swap, swapoff */
+struct swap_unuse {
+ int (*func)(unsigned int type, void *arg);
+ void *arg;
+ struct swap_unuse *prev;
+ struct swap_unuse *next;
+};
+void register_swap_unuse_function (struct swap_unuse *swap_unuse);
+void unregister_swap_unuse_function (struct swap_unuse *swap_unuse);
+
/*
* vm_ops not present page codes for shared memory.
*
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.1.101.x0/ipc/shm.c linux-2.1.101.x2/ipc/shm.c
--- linux-2.1.101.x0/ipc/shm.c Wed Jun 3 22:54:23 1998
+++ linux-2.1.101.x2/ipc/shm.c Thu Jun 4 09:23:28 1998
@@ -30,6 +30,8 @@
static void shm_open (struct vm_area_struct *shmd);
static void shm_close (struct vm_area_struct *shmd);
static pte_t shm_swap_in(struct vm_area_struct *, unsigned long, unsigned long);
+static int shm_try_to_unuse_seg(struct shmid_ds *shp, unsigned int type);
+static int shm_try_to_unuse(unsigned int type, void *arg);
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 */
@@ -45,6 +47,11 @@
static ulong swap_successes = 0;
static ulong used_segs = 0;
+/* swap off */
+static struct swap_unuse shm_swap_unuse = {
+ shm_try_to_unuse, 0, 0, 0
+};
+
__initfunc(void shm_init (void))
{
int id;
@@ -53,6 +60,7 @@
shm_segs[id] = (struct shmid_ds *) IPC_UNUSED;
shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
shm_lock = NULL;
+ register_swap_unuse_function(&shm_swap_unuse);
return;
}
@@ -830,4 +838,56 @@
shm_swp++;
shm_rss--;
return 1;
+}
+
+/* Swap off support */
+static int shm_try_to_unuse_seg(struct shmid_ds *shp, unsigned int type)
+{
+ unsigned long page = 0;
+ int i, numpages;
+ numpages = shp->shm_npages;
+ for (i = 0; i < numpages; i++) {
+ pte_t pte;
+ if (!page) {
+ page = get_free_page(GFP_KERNEL);
+ }
+ pte = __pte(shp->shm_pages[i]);
+ if (pte_none(pte))
+ continue;
+ if (pte_present(pte))
+ continue;
+ if (!page)
+ return -1;
+ rw_swap_page_nocache(READ, pte_val(pte), (char *)page);
+ pte = __pte(shp->shm_pages[i]);
+ if (!pte_present(pte)) {
+ swap_free(pte_val(pte));
+ shm_swp--;
+ shm_rss++;
+ pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
+ shp->shm_pages[i] = pte_val(pte);
+ }
+ }
+ if (page) {
+ free_page(page);
+ page = 0;
+ }
+ return 0;
+}
+
+static int shm_try_to_unuse(unsigned int type, void *arg)
+{
+ int id;
+ struct shmid_ds *ident;
+ for(id = 0; id < SHMMNI; id++) {
+ ident = shm_segs[id];
+ if ((ident != (struct shmid_ds *) IPC_UNUSED) &&
+ (ident != (struct shmid_ds *) IPC_NOID)) {
+ int result;
+ result = shm_try_to_unuse_seg(ident, type);
+ if (result != 0)
+ return -1;
+ }
+ }
+ return 0;
}
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.1.101.x0/mm/Makefile linux-2.1.101.x2/mm/Makefile
--- linux-2.1.101.x0/mm/Makefile Tue May 12 14:17:54 1998
+++ linux-2.1.101.x2/mm/Makefile Wed Jun 3 22:21:51 1998
@@ -12,4 +12,6 @@
vmalloc.o slab.o \
swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
+OX_OBJS := swap_syms.o
+
include $(TOPDIR)/Rules.make
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.1.101.x0/mm/swap_syms.c linux-2.1.101.x2/mm/swap_syms.c
--- linux-2.1.101.x0/mm/swap_syms.c Wed Dec 31 18:00:00 1969
+++ linux-2.1.101.x2/mm/swap_syms.c Wed Jun 3 22:21:51 1998
@@ -0,0 +1,15 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+
+/* Explicit swapping */
+EXPORT_SYMBOL(rw_swap_page);
+EXPORT_SYMBOL(rw_swap_page_nocache);
+EXPORT_SYMBOL(swap_free);
+EXPORT_SYMBOL(get_swap_page);
+EXPORT_SYMBOL(si_swapinfo);
+EXPORT_SYMBOL(register_swap_unuse_function);
+EXPORT_SYMBOL(unregister_swap_unuse_function);
+EXPORT_SYMBOL(swapper_inode);
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.1.101.x0/mm/swapfile.c linux-2.1.101.x2/mm/swapfile.c
--- linux-2.1.101.x0/mm/swapfile.c Tue May 12 14:17:54 1998
+++ linux-2.1.101.x2/mm/swapfile.c Wed Jun 3 22:21:51 1998
@@ -298,7 +298,7 @@
* and then search for the process using it. All the necessary
* page table adjustments can then be made atomically.
*/
-static int try_to_unuse(unsigned int type)
+static int try_to_unuse_processes(unsigned int type, void *dummy)
{
struct swap_info_struct * si = &swap_info[type];
struct task_struct *p;
@@ -345,6 +345,69 @@
}
}
return 0;
+}
+
+struct swap_unuse unuse_processes =
+{
+ try_to_unuse_processes,
+ NULL,
+ &unuse_processes,
+ &unuse_processes
+};
+
+/* Don't add or remove unuse functions while a swapoff is in progress.
+ * It reduces some theoretical races.
+ */
+static int swap_unuse_lock = 0;
+static struct wait_queue *swap_unuse_wait = NULL;
+
+static int try_to_unuse(unsigned int type)
+{
+ int error = 0;
+ struct swap_unuse *unuse_func, *next_func;
+ next_func = unuse_processes.next;
+ swap_unuse_lock = 1;
+ do {
+ unuse_func = next_func;
+ next_func = unuse_func->next;
+ error = unuse_func->func(type, unuse_func->arg);
+ if (error) {
+ return error;
+ }
+ } while (unuse_func != &unuse_processes);
+ swap_unuse_lock = 0;
+ wake_up(&swap_unuse_wait);
+ return 0;
+}
+
+void register_swap_unuse_function (struct swap_unuse *swap_unuse)
+{
+ if (!swap_unuse) {
+ return;
+ }
+ while (swap_unuse_lock) {
+ sleep_on(&swap_unuse_wait);
+ }
+ swap_unuse->prev = &unuse_processes;
+ swap_unuse->next = unuse_processes.next;
+ unuse_processes.next->prev = swap_unuse;
+ unuse_processes.next = swap_unuse;
+}
+
+void unregister_swap_unuse_function (struct swap_unuse *swap_unuse)
+{
+ struct swap_unuse *next;
+ if (!swap_unuse) {
+ return;
+ }
+ while (swap_unuse_lock) {
+ sleep_on(&swap_unuse_wait);
+ }
+ next = swap_unuse->next;
+ next->prev = swap_unuse->prev;
+ next->prev->next = next;
+
+ swap_unuse->next = swap_unuse->prev = NULL;
}
asmlinkage int sys_swapoff(const char * specialfile)
next prev parent reply other threads:[~1998-06-11 14:20 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <356478F0.FE1C378F@star.net>
1998-05-24 17:28 ` patch for 2.1.102 swap code Stephen C. Tweedie
1998-05-25 10:07 ` David S. Miller
1998-05-25 12:38 ` Eric W. Biederman
1998-05-26 21:52 ` Stephen C. Tweedie
1998-06-11 14:31 ` Eric W. Biederman [this message]
1998-06-12 21:29 ` Stephen C. Tweedie
1998-05-25 12:52 ` Bill Hawes
1998-05-25 13:42 ` David S. Miller
1998-05-26 18:00 ` Stephen C. Tweedie
1998-05-26 21:38 ` Stephen C. Tweedie
1998-05-26 21:46 ` Rik van Riel
1998-06-02 22:21 ` Stephen C. Tweedie
1998-05-27 15:27 ` Bill Hawes
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=m167i857t1.fsf@flinx.npwt.net \
--to=ebiederm+eric@npwt.net \
--cc=linux-mm@kvack.org \
--cc=sct@dcs.ed.ac.uk \
/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