New syscall (rough draft), swap_out_pid()

George (greerga@nidhogg.ham.muohio.edu)
Tue, 17 Mar 1998 00:04:43 -0500 (EST)


Basically I got tired of seeing processes hanging around in memory when I
knew they weren't going to use it. This will swap out portions of a
program and so far hasn't bombed on my computer. It probably needs a
suser() check but this is preliminary anyway just to see what people think.
It works in chunks so it has to be called repeatedly at the moment. I
don't know if this will swap out too much than swap space, haven't tested
that part. I do know, however, that if you try to swap out a process that
is running, it won't kill the process because it'll simply be swapped back
in when it needs something.

This is the program I currently have to use the pid, it's very dirty, I
call it sop.c for swap_out_pid():

#include <syscall.h>
#include <linux/types.h>
#include <stdio.h>

_syscall1(int,swap_out_pid,__kernel_pid_t,pid);

int main(int argc, char **argv)
{
int i = 0, r;
while (i < 10) {
r = swap_out_pid(atoi(argv[1]));
i += (r == 0);
printf("%d ", r);
}
return 0;
}

The numbers it prints out I surmise to be the number of pages it swapped to
disk but I'll check later when I actually clean this up. As noted above,
this is really rough, it doesn't even check what is given to the syscall.
(Which, btw, may currently happily oops if you forget to put an argument
in.) I considered a module approach but this was so easy I made it a
function. I couldn't get it to work like sys_close() (without the icky
prototype at the top of the program) but I did at least get it to link
properly. I noticed that the GFP_ mask is passed all over through about 10
different functions but don't know whether this application should have
one.

diff -upr linux/arch/i386/kernel/entry.S linux-2.1.89/arch/i386/kernel/entry.S
--- linux/arch/i386/kernel/entry.S Mon Feb 9 14:27:08 1998
+++ linux-2.1.89/arch/i386/kernel/entry.S Sun Mar 15 21:26:47 1998
@@ -533,7 +533,8 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_pread) /* 180 */
.long SYMBOL_NAME(sys_pwrite)
.long SYMBOL_NAME(sys_chown)
-
- .rept NR_syscalls-182
+ .long SYMBOL_NAME(sys_swap_out_pid)
+
+ .rept NR_syscalls-183
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff -upr linux/include/asm-i386/unistd.h linux-2.1.89/include/asm-i386/unistd.h
--- linux/include/asm-i386/unistd.h Mon Feb 9 14:27:27 1998
+++ linux-2.1.89/include/asm-i386/unistd.h Sun Mar 15 21:48:57 1998
@@ -188,6 +188,7 @@
#define __NR_pread 180
#define __NR_pwrite 181
#define __NR_chown 182
+#define __NR_swap_out_pid 183

/* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */

@@ -296,6 +297,7 @@ static inline _syscall3(int,open,const c
static inline _syscall1(int,close,int,fd)
static inline _syscall1(int,_exit,int,exitcode)
static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,swap_out_pid,pid_t,pid)

static inline pid_t wait(int * wait_stat)
{
diff -upr linux/include/linux/mm.h linux-2.1.89/include/linux/mm.h
--- linux/include/linux/mm.h Sat Mar 7 00:02:12 1998
+++ linux-2.1.89/include/linux/mm.h Sun Mar 15 22:27:33 1998
@@ -297,6 +297,8 @@ extern void truncate_inode_pages(struct
extern unsigned long get_cached_page(struct inode *, unsigned long, int);
extern void put_cached_page(unsigned long);

+extern asmlinkage int sys_swap_out_pid(pid_t pid);
+
/*
* GFP bitmasks..
*/
diff -upr linux/kernel/ksyms.c linux-2.1.89/kernel/ksyms.c
--- linux/kernel/ksyms.c Sat Mar 7 00:10:16 1998
+++ linux-2.1.89/kernel/ksyms.c Sun Mar 15 21:56:31 1998
@@ -73,6 +73,7 @@ extern char *get_options(char *str, int
extern void set_device_ro(kdev_t dev,int flag);
extern struct file_operations * get_blkfops(unsigned int);
extern int blkdev_release(struct inode * inode);
+extern int sys_swap_out_pid(pid_t pid);
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
extern int (*do_nfsservctl)(int, void *, void *);
#endif
@@ -119,6 +120,7 @@ EXPORT_SYMBOL(exit_mm);
EXPORT_SYMBOL(exit_files);
EXPORT_SYMBOL(exit_fs);
EXPORT_SYMBOL(exit_sighand);
+EXPORT_SYMBOL(sys_swap_out_pid);

/* internal kernel memory management */
EXPORT_SYMBOL(__get_free_pages);
diff -upr linux/mm/vmscan.c linux-2.1.89/mm/vmscan.c
--- linux/mm/vmscan.c Wed Mar 4 21:00:09 1998
+++ linux-2.1.89/mm/vmscan.c Mon Mar 16 23:51:32 1998
@@ -324,7 +324,7 @@ static int swap_out_vma(struct task_stru
return 0;
}
/* [ Mailer note: This probably doesn't need to have static removed...
I had the function in it's own file previous to this patch. ] */
-static int swap_out_process(struct task_struct * p, int gfp_mask)
+int swap_out_process(struct task_struct * p, int gfp_mask)
{
unsigned long address;
struct vm_area_struct* vma;
@@ -633,4 +633,18 @@ void init_swap_timer(void)
timer_table[SWAP_TIMER].expires = 0;
timer_table[SWAP_TIMER].fn = swap_tick;
timer_active |= (1<<SWAP_TIMER);
+}
+
+asmlinkage int sys_swap_out_pid(pid_t pid)
+{
+ int error;
+ struct task_struct *swap_task;
+ lock_kernel();
+ printk("Finding task...\n");
+ swap_task = find_task_by_pid(pid);
+ printk("Found task at %p, attempting swapout...\n", swap_task);
+ error = swap_out_process(swap_task, 0);
+ printk("Swapped out pid #%d, error code %d.\n", pid, error);
+ unlock_kernel();
+ return error;
}

Comments?

-George

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu