patch for migshm(for 2.4.26-om1)
Ratna Manoj Bolla <[email protected]>
| Newsgroups | gmane.linux.cluster.openmosix.devel |
|---|---|
| Message-ID | <[email protected]> |
Below is the patch for MigShm.
- No STAY_FOR_MONKEY flag
- implemented Distributed shared memory.
- MAP_SHARED mappings can now migrate.
-more debugging has to be done.
plz report bugs and suggestions.
below is my one of the test program followed by patch.
#include<stdio.h>
#include<sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
char *pid2proc_path(int);
char path[50];
int b[80];
main() {
int fd = open("om_file",O_RDWR);
char *a = mmap(0,4096*15,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
int i = 0;
unsigned long k=0;
char *b =a;// mmap(0,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);
fork();
fork();
fork();
fork();
while(k++ <= 0xffffff00); k=0;
while(k++ <= 0xffffff00); k=0;
// while(k++ <= 0xffffff00); k=0;
// while(k++ <= 0xffffff00); k=0;
// while(k++ <= 0xffffff00); k=0;
char ch = 'A';
while(1) {
i++;
if(i== 15000)
break;
// sleep(1);
if(ch == 'Z')
ch = 'A';
*a = ch;
// sleep(1);
printf("p:%d-%c\n",i,*a);
a+=3;
ch++;
}
}
Patch:
diff -Naur linux-2.4.26-om1/fs/file_table.c linux-2.4.26-om1-o/fs/file_table.c
--- linux-2.4.26-om1/fs/file_table.c 2006-05-08 15:01:47.000000000 +0530
+++ linux-2.4.26-om1-o/fs/file_table.c 2006-05-07 17:56:02.000000000 +0530
@@ -13,6 +13,7 @@
#include <linux/smp_lock.h>
#include <linux/iobuf.h>
+#include <hpc/mig_shm.h>
/* sysctl tunables... */
struct files_stat_struct files_stat = {0, 0, NR_FILE};
@@ -104,8 +105,12 @@
struct inode * inode = dentry->d_inode;
if (atomic_dec_and_test(&file->f_count)) {
+#ifdef CONFIG_MOSIX + if(current->mosix.dflags & DREMOTE) +
shm_send_message(current->mosix.deppe,(struct shm_page
*)(home_file(file)),NULL,PUT_FILE);
+#endif /* CONFIG_MOSIX */
locks_remove_flock(file);
-
+
if (file->f_iobuf)
free_kiovec(1, &file->f_iobuf);
diff -Naur linux-2.4.26-om1/fs/read_write.c linux-2.4.26-om1-o/fs/read_write.c
--- linux-2.4.26-om1/fs/read_write.c 2006-05-08 15:01:50.000000000 +0530
+++ linux-2.4.26-om1-o/fs/read_write.c 2006-05-07 17:56:02.000000000 +0530
@@ -169,10 +169,26 @@
}
#endif
+#ifdef CONFIG_MOSIX
+
+extern void
+put_pages(struct address_space *mapping,loff_t offset,size_t count,int
writer,unsigned long error);
+
+extern unsigned long
+get_pages(struct address_space *mapping,loff_t offset,size_t count,int
writer);
+
+#endif /* CONFIG_MOSIX */
+
+
+
asmlinkage ssize_t sys_read(unsigned int fd, char * buf, size_t count)
{
ssize_t ret;
struct file * file;
+#ifdef CONFIG_MOSIX
+ unsigned long error=0;
+ loff_t offset;
+#endif /* CONFIG_MOSIX */
#ifdef CONFIG_MOSIX_DFSA
dfsa_syscall_on_file(fd, 1);
@@ -186,10 +202,23 @@
if (!ret) {
ssize_t (*read)(struct file *, char *, size_t,
loff_t *);
ret = -EINVAL;
- if (file->f_op && (read = file->f_op->read) !=
NULL)
- ret = read(file, buf, count,
&file->f_pos);
+ if (file->f_op && (read = file->f_op->read) !=
NULL) +#ifdef CONFIG_MOSIX
+ {
+ error =
get_pages(file->f_dentry->d_inode->i_mapping,(offset = file->f_pos),count,0);
+ if(!error)
+#endif /* CONFIG_MOSIX */ + ret =
read(file, buf, count, &file->f_pos); +#ifdef CONFIG_MOSIX +
put_pages(file->f_dentry->d_inode->i_mapping,offset,count,0,error); +
}
+#endif /* CONFIG_MOSIX */
}
}
+
+ if(error)
+ ret = -1;
+
if (ret > 0)
dnotify_parent(file->f_dentry, DN_ACCESS);
fput(file);
@@ -201,6 +230,10 @@
{
ssize_t ret;
struct file * file;
+#ifdef CONFIG_MOSIX
+ unsigned long error=0;
+ loff_t offset;
+#endif /* CONFIG_MOSIX */
#ifdef CONFIG_MOSIX_DFSA
dfsa_syscall_on_file(fd, 1);
@@ -215,10 +248,23 @@
if (!ret) {
ssize_t (*write)(struct file *, const char *,
size_t, loff_t *);
ret = -EINVAL;
- if (file->f_op && (write = file->f_op->write)
!= NULL)
- ret = write(file, buf, count,
&file->f_pos);
- }
+ if (file->f_op && (write = file->f_op->write)
!= NULL) +#ifdef CONFIG_MOSIX
+ {
+ error =
get_pages(file->f_dentry->d_inode->i_mapping,(offset = file->f_pos),count,1);
+ + if(!error)
+#endif /* CONFIG_MOSIX */
+ ret = write(file, buf, count,
&file->f_pos);
+#ifdef CONFIG_MOSIX +
put_pages(file->f_dentry->d_inode->i_mapping,offset,count,1,error);
+ }
+#endif /* CONFIG_MOSIX */ + }
}
+
+ if(error)
+ ret = -1;
if (ret > 0)
dnotify_parent(file->f_dentry, DN_MODIFY);
fput(file);
diff -Naur linux-2.4.26-om1/hpc/comm.c linux-2.4.26-om1-o/hpc/comm.c
--- linux-2.4.26-om1/hpc/comm.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/comm.c 2006-05-07 17:56:02.000000000 +0530
@@ -31,7 +31,6 @@
#define MIG_DAEMON_PORT 0x3412
#define INFO_DAEMON_PORT 0x3415
-
/*
* mosix specific data per contact
*/
@@ -65,7 +64,7 @@
#define COMM_SOCKET_BUFFER 131072
#define COMM_REMOTE_TIMO ((unsigned long) 200*HZ) /* changed form
300 */
-#define COMM_CONNECT_TIMO ((unsigned long) 4*HZ) /* changed from 5 */
+#define COMM_CONNECT_TIMO ((unsigned long) 10*HZ) /* changed from 5 */
#define COMM_RECONN_TIMO ((unsigned long) 10*HZ)
#ifdef CONFIG_MOSIX_DFSA
@@ -171,7 +170,6 @@
static int comm_waitaccept(void);
static int comm_poll(int, int, unsigned long);
static void comm_data_ready(struct sock *, int);
-static int comm_getname(struct socket *, struct sockaddr *);
static void comm_shutdown(mosix_link *);
static inline struct socket *comm_set_address(int, struct sockaddr *, int);
@@ -315,8 +313,6 @@
him = ((int *) ptr)[0];
me = ((int *) ptr)[1];
- if (him & 0x80000000)
- rinode_flush_files(him & ~0x80000000);
if (comm_getpeer(current->mosix.contact) == (him & 0x7fffffff)
&& PE == me)
ret = 2 * sizeof (int);
@@ -367,6 +363,8 @@
*/
switch (mos) {
+ case MIGSHM_COMM: + case COMM_MIGSHM:
case COMM_INFO:
sock->sk->data_ready = comm_data_ready;
break;
@@ -493,6 +491,8 @@
case COMM_LOOSE:
bind = 0;
/* fall through */
+ case MIGSHM_COMM:
+ case COMM_MIGSHM:
case COMM_INFO:
listen = 0;
/* fall through */
@@ -763,7 +763,7 @@
mosix_panic("comm_free() # 1");
out:
-
+ return;
}
/*
@@ -1564,6 +1564,7 @@
return (error);
}
+unsigned long AVG_TRIES = 2;
/*
* comm_recvfrom() - receive a datagram from someone
* NOTE NOTE NOTE: the timeout is in microseconds -- NOT ticks!
@@ -1580,7 +1581,14 @@
int error;
int nrecv = len, msgflg = 0;
DECLARE_WAITQUEUE(wait, current);
+ unsigned long tries = LONG_MAX;
+ unsigned long for_avg = 0;
+ if (timo == GTIME_OUT)
+ tries = 3 * AVG_TRIES-1;
+ else if (timo == INT_TIME_OUT)
+ tries = 4 * AVG_TRIES * NPE - 1;
+ else
if (timo) {
#if MILLION % HZ
timo = timo * HZ / MILLION;
@@ -1591,13 +1599,13 @@
oldfs = get_fs();
set_fs(KERNEL_DS);
- if (timo)
- msgflg |= MSG_DONTWAIT;
+ if(timo == GTIME_OUT || timo == INT_TIME_OUT || !timo)
+ timo = MAX_SCHEDULE_TIMEOUT;
else
- timo = MAX_SCHEDULE_TIMEOUT;
+ msgflg |= MSG_DONTWAIT;
add_wait_queue(mlink->sock->sk->sleep, &wait);
- while (1) {
+ while (tries) {
set_current_state(msgflg ? TASK_UNINTERRUPTIBLE :
TASK_INTERRUPTIBLE);
@@ -1622,6 +1630,10 @@
error = -EINTR;
break;
}
+ if(tries != LONG_MAX) {
+ tries--;
+ for_avg++;
+ }
}
remove_wait_queue(mlink->sock->sk->sleep, &wait);
set_current_state(TASK_RUNNING);
@@ -1629,6 +1641,12 @@
if (msg.msg_flags & MSG_TRUNC) {
error = -EDIST;
+ } else if(!tries)
+ error = -ETIME;
+ else if (tries != LONG_MAX ) {
+ AVG_TRIES = (AVG_TRIES + for_avg) / 2;
+ if(AVG_TRIES < 2)
+ AVG_TRIES = 2;
}
return (error);
@@ -1681,7 +1699,7 @@
/*
* comm_getname: fill in our name
*/
-static int
+int
comm_getname(struct socket *sock, struct sockaddr *saddr)
{
switch (comm_type) {
@@ -1741,6 +1759,7 @@
case COMM_TOADDR:
/* address was set by the caller */
break;
+ case COMM_MIGSHM:
case COMM_INFO:
proto = IPPROTO_UDP;
type = SOCK_DGRAM;
@@ -1751,10 +1770,17 @@
sa->sin_addr.s_addr = INADDR_ANY;
if (mos == COMM_MIGD)
sa->sin_port = MIG_DAEMON_PORT;
- else
+ else if(mos == COMM_INFO)
sa->sin_port = INFO_DAEMON_PORT;
+ else if(mos == COMM_MIGSHM)
+ sa->sin_port = MIGSHM_DEAMON_PORT;
break;
case COMM_ACCEPT:
+ case MIGSHM_COMM:
+ if(mos == MIGSHM_COMM) {
+ type = SOCK_DGRAM;
+ proto = IPPROTO_UDP;
+ }
memset((void *) sa, 0, sizeof (struct sockaddr_in));
sa->sin_family = AF_INET;
sa->sin_addr.s_addr = INADDR_ANY;
diff -Naur linux-2.4.26-om1/hpc/deputy.c linux-2.4.26-om1-o/hpc/deputy.c
--- linux-2.4.26-om1/hpc/deputy.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/deputy.c 2006-05-07 17:56:02.000000000 +0530
@@ -24,6 +24,9 @@
#include <asm/mmu_context.h>
#include <linux/smp_lock.h>
#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
#ifdef CONFIG_MOSIX_DFSA
#include <hpc/dfsa.h>
#endif /* CONFIG_MOSIX_DFSA */
@@ -343,27 +346,30 @@
deputy_handle_interim_request(int type, void *head, int hlen)
{
switch (type) {
- case REM_NOTHING:
- comm_free(head);
- return (comm_send(REM_NOTHING | REPLY, NULL, 0, NULL, 0, 0));
- case REM_PAGE:
- return (deputy_bring_page((struct bring_page_h *) head));
- case REM_GETTSC:
- return (deputy_tsc());
- case REM_MORESTRINGS:
- return (deputy_more_strings
- ((struct execve_more_strings_h *) head));
- case REM_BRING_ME_REGS:
- return (deputy_bring_me_regs((unsigned long *) head));
- case REM_GETALOAD:
- return (send_local_aload(REM_GETALOAD | REPLY));
- default:
- printk("Process %s, uid=%d, received an unexpected "
- "urgent request\n" "(type 0x%x) from the "
- "remote site where it was running\n",
- desc_mostask(NULL), current->uid, type);
- comm_free(head);
- return (-EDIST);
+
+ case REM_UPGRADE:
+ return(deputy_upgrade((struct upgrade_h *)head));
+ case REM_NOTHING:
+ comm_free(head);
+ return (comm_send(REM_NOTHING | REPLY, NULL, 0, NULL,
0, 0));
+ case REM_PAGE:
+ return (deputy_bring_page((struct bring_page_h *)
head));
+ case REM_GETTSC:
+ return (deputy_tsc());
+ case REM_MORESTRINGS:
+ return (deputy_more_strings
+ ((struct execve_more_strings_h *) head));
+ case REM_BRING_ME_REGS:
+ return (deputy_bring_me_regs((unsigned long *) head));
+ case REM_GETALOAD:
+ return (send_local_aload(REM_GETALOAD | REPLY));
+ default:
+ printk("Process %s, uid=%d, received an unexpected "
+ "urgent request\n" "(type 0x%x) from the "
+ "remote site where it was running\n",
+ desc_mostask(NULL), current->uid, type);
+ comm_free(head);
+ return (-EDIST);
}
}
@@ -431,29 +437,29 @@
unsigned long
mosix_deputy_mmap(struct file *fp, unsigned long addr, int fixed,
- unsigned long len, unsigned long flags, unsigned long off,
- off_t isize, nopage_t nopage)
+ unsigned long len, unsigned long flags, unsigned long off,
+ off_t isize, nopage_t nopage)
{
- struct mmap_parameters_h mp;
- int error;
- unsigned long result;
-
- mp.addr = addr;
- mp.fixed = fixed;
- mp.len = len;
- mp.flags = flags;
- mp.pgoff = off;
- mp.origin = PE;
- if ((mp.fp = fp)) {
- mp.dp = fp->f_dentry;
- mp.uniq = mp.fp->f_dentry->d_inode->i_unique;
- mp.isize = mp.fp->f_dentry->d_inode->i_size;
- }
- mp.nopage = nopage;
- if ((error = deputy_request(DEP_MMAP, &mp, sizeof (mp), NULL, 0, 0,
- (void **) &result, -sizeof (result))))
- return (error);
- return (result);
+ struct mmap_parameters_h mp;
+ int error;
+ unsigned long result;
+
+ mp.addr = addr;
+ mp.fixed = fixed;
+ mp.len = len;
+ mp.flags = flags;
+ mp.pgoff = off;
+ mp.origin = PE;
+ if ((mp.fp = fp)) {
+ mp.dp = fp->f_dentry;
+ mp.uniq = mp.fp->f_dentry->d_inode->i_unique;
+ mp.isize = mp.fp->f_dentry->d_inode->i_size;
+ }
+ mp.nopage = nopage;
+ if ((error = deputy_request(DEP_MMAP, &mp, sizeof (mp), NULL, 0, 0,
+ (void **) &result, -sizeof (result))))
+ return (error);
+ return (result);
}
long
@@ -519,9 +525,6 @@
case FATAL_SIGSEGV:
force_sig(SIGSEGV, current);
break;
- case REMOTE_FILE_RELEASED:
- mosix_rebuild_file_list();
- break;
case SIGSEGV:
case SIGKILL:
case SIGVTALRM:
@@ -910,31 +913,118 @@
}
int
+deputy_upgrade(struct upgrade_h *u)
+{
+ struct shm_page *shm_page = u->rem_shm_page_addr;
+ struct page *page = NULL;
+ struct shm_page_ret_h r;
+ int err;
+
+
+ spin_lock(&shm_page->shm_lock);
+ if((shm_page->state & PERM_ERR) || (shm_page->state & UPGRADE_ERR))
+ r.ret = 2;
+ else
+ if(((shm_page->state & STATE_MASK) == SHARED) && !(shm_page->state &
DROPPING) && (!shm_page->readers)) {
+ shm_page->state &= ~SHARED;
+ shm_page->state |= BUSY_EXCLUSIVE;
+
+ spin_unlock(&shm_page->shm_lock);
+ page = find_get_page(shm_page->mapping,shm_page->index);
+
+ if(page) {
+ invalidate(shm_page,page,1);
+ page_cache_release(page);
+ }
+
+
+ shm_send_message(0,shm_page,NULL,DROP_NEXTPREV);
+
+ shm_page->next = shm_page->prev = PE;
+ shm_page->next_addr = shm_page->prev_addr = shm_page;
+
+ spin_lock(&shm_page->shm_lock);
+ shm_page->owner = current->mosix.whereami;
+ shm_page->rem_shm_page_addr = u->shm_page;
+ + shm_page->state &= ~BUSY_EXCLUSIVE;
+ shm_page->state |= EXCLUSIVE;
+ r.ret = 0;
+ } else
+ r.ret = 1;
+
+ spin_unlock(&shm_page->shm_lock);
+ + comm_free(u);
+ cli();
+ r.deputytime = current->mosix.deputytime;
+ current->mosix.deputytime = 0;
+ sti();
+ err = deputy_reply(REM_UPGRADE, &r, sizeof (r),NULL, 0, 0,2);
+
+ return err;
+} +int
deputy_bring_page(struct bring_page_h *b)
{
struct file *fp = b->fp;
struct vm_area_struct v;
- struct page_ret_h r;
+ struct shm_page_ret_h r;
int err;
int address = b->offset;
struct page *page;
struct task_struct *p = current;
+ struct shm_page *shm_page=NULL;
+
+ struct vm_operations_struct file_vm_ops = {
+ nopage: b->nopage,
+ };
+
v.vm_start = v.vm_pgoff = 0;
v.vm_end = address + PAGE_SIZE;
v.vm_mm = p->mm; /* (eg. NULL) */
v.vm_file = fp;
- v.vm_flags = 0; /* anything really, but VM_SHARED */
+ v.vm_ops = &file_vm_ops;
+ + v.vm_flags = (unsigned long)b->rem_shm_page_addr;
deeper_sleep();
- page = b->nopage(&v, address, 0);
+
+ page = get_nopage(&v, address, &shm_page, (b->access & WITH_WRITE_ACC)
? 1 : 0);
+
lighter_sleep();
if (page == NOPAGE_OOM) {
r.ret = -ENOMEM;
- page = 0;
- } else
- r.ret = page ? 0 : -EFBIG;
- comm_free(b);
+ page = NULL;
+ } else if(page == PAGE_BUSY) {
+ page = NULL;
+ r.ret = -EBUSY;
+ }
+ else + r.ret = (page ? 0 : -EINVAL);
+
+ if(page && (b->access & (WITH_WRITE_ACC|WITH_READ_ACC))) {
+
+ r.rem_shm_page_addr = shm_page;
+
+ if(b->access & WITH_WRITE_ACC ) {
+ if((!(v.vm_start)) && (!(v.vm_end))) {
+ r.next = 0;
+ r.next_addr = NULL;
+ } else {
+ r.next_addr = (struct shm_page *)v.vm_start;
+ r.next = v.vm_end;
+ }
+ } else {
+ r.next = PE;
+ r.next_addr = shm_page;
+ r.prev = v.vm_end;
+ r.prev_addr = (struct shm_page *)(v.vm_start);
+ }
+
+ }
+
cli();
r.deputytime = p->mosix.deputytime;
p->mosix.deputytime = 0;
@@ -942,13 +1032,77 @@
err = deputy_reply(REM_PAGE, &r, sizeof (r),
page ? kmap(page) : NULL, page ? PAGE_SIZE : 0, 0,
2);
- if (page) {
- kunmap(page);
- __free_page(page);
+
+ if(shm_page) {
+ if(err) {
+ if(b->access & WITH_WRITE_ACC) {
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~BUSY_EXCLUSIVE; +
if(!(v.vm_start) && !(v.vm_end)) {
+ shm_page->state |= EXCLUSIVE;
+ shm_page->owner = PE;
+ shm_page->prev = shm_page->next = PE;
+ shm_page->next_addr =
shm_page->prev_addr = shm_page;
+ spin_unlock(&shm_page->shm_lock);
+ shm_pagecache_release(shm_page);
+ } else {
+ shm_page->state |= (SHARED|DROPPING);
+ spin_unlock(&shm_page->shm_lock);
+ shm_page->next = PE;
+ shm_page->next_addr = shm_page;
+
if(shm_send_message(shm_page->prev,shm_page,NULL,DROP_NEXT)) {
+ printk(KERN_ERR "reader loop
broken because of %d Reboot all\n",shm_page->prev); +
shm_page->owner = shm_page->next = shm_page->prev = PE;
+ shm_page->next_addr =
shm_page->prev_addr = shm_page;
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &=
~(SHARED|DROPPING);
+ shm_page->state |= EXCLUSIVE;
+
spin_unlock(&shm_page->shm_lock);
+
shm_pagecache_release(shm_page);
+ goto out;
+ }
+ shm_page->next = v.vm_end;
+ shm_page->next_addr = (struct shm_page
*)v.vm_start;
+ shm_page->state &= ~DROPPING;
+ } + } else {
+ spin_lock(&shm_page->shm_lock);
+ if(shm_page->next == current->mosix.whereami) {
+ shm_page->prev = shm_page->next = PE;
+ shm_page->prev_addr =
shm_page->next_addr = shm_page;
+ } else {
+ shm_page->prev = v.vm_end;
+ shm_page->prev_addr = (struct shm_page
*)(v.vm_start);
+ }
+ shm_page->state &= ~DROPPING;
+ spin_unlock(&shm_page->shm_lock);
+ }
+ } else {
+ if(b->access & WITH_WRITE_ACC) {
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~BUSY_EXCLUSIVE;
+ shm_page->state |= EXCLUSIVE;
+ shm_page->owner = current->mosix.whereami;
+ shm_page->rem_shm_page_addr =
b->rem_shm_page_addr;
+ shm_page->prev = shm_page->next = PE;
+ shm_page->next_addr =
shm_page->prev_addr = shm_page; +
spin_unlock(&shm_page->shm_lock);
+ } + } + out:
+ shm_pagecache_release(shm_page);
}
+ + comm_free(b);
+ if (page) {
+ kunmap(page);
+ __free_page(page);
+ }
return (err);
}
+
+
int
deputy_tsc(void)
{
@@ -1143,8 +1297,7 @@
if (deputy_request(DEP_EXEC_MMAP, NULL, 0, NULL, 0, 0,
(void **) &r, -sizeof (r)))
return (-ENOMEM);
- if (!r)
- mosix_clear_all_held_files(current);
+
return (r);
}
diff -Naur linux-2.4.26-om1/hpc/init.c linux-2.4.26-om1-o/hpc/init.c
--- linux-2.4.26-om1/hpc/init.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/init.c 2006-05-07 17:56:02.000000000 +0530
@@ -28,6 +28,30 @@
void
init_mosix(void)
{
+ extern struct super_block bad_super_block;
+ static struct super_operations empty_sops = {};
+ struct super_block *s = &bad_super_block;
+ if (s) {
+ memset(s, 0, sizeof(struct super_block));
+ INIT_LIST_HEAD(&s->s_dirty);
+ INIT_LIST_HEAD(&s->s_locked_inodes);
+ INIT_LIST_HEAD(&s->s_files);
+ INIT_LIST_HEAD(&s->s_instances);
+ init_rwsem(&s->s_umount);
+ sema_init(&s->s_lock, 1);
+ down_write(&s->s_umount);
+ s->s_count = S_BIAS;
+ atomic_set(&s->s_active, 1);
+ sema_init(&s->s_vfs_rename_sem,1);
+ sema_init(&s->s_nfsd_free_path_sem,1);
+ sema_init(&s->s_dquot.dqio_sem, 1);
+ sema_init(&s->s_dquot.dqoff_sem, 1);
+ s->s_maxbytes = MAX_NON_LFS;
+ s->s_op = &empty_sops;
+ s->dq_op = NULL;
+ s->s_qcop = NULL;
+ }
+
extern int x86_udelay_tsc;
cpuspeed = ((int64_t) loops_per_jiffy) * STD_SPD / STD_LOOPS;
if (!x86_udelay_tsc)
@@ -43,4 +67,5 @@
mosinfo_update_gateways();
kernel_thread(mosix_info_daemon, NULL, 0);
kernel_thread(mosix_mem_daemon, NULL, 0);
+ kernel_thread(mosix_migshm_daemon,NULL,0);
}
diff -Naur linux-2.4.26-om1/hpc/kernel.c linux-2.4.26-om1-o/hpc/kernel.c
--- linux-2.4.26-om1/hpc/kernel.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/kernel.c 2006-05-07 17:56:02.000000000 +0530
@@ -555,8 +555,6 @@
m->stay |= DSTAY_SYSTEM;
else
m->stay &= ~DSTAY_SYSTEM;
- m->held_files = NULL;
- m->held_allocated = 0;
rwlock_init(&m->state_lock);
m->contact = 0;
m->ucache = NULL;
@@ -597,7 +595,7 @@
init_waitqueue_head(mos_to_waitp(m));
m->mosix_log = NULL;
m->dirty_bits = 0;
- return (fork_mosix_remote_files(p));
+ return 0;
}
void
@@ -729,63 +727,6 @@
m->pass_regs = 0;
}
-void
-mosix_bring_monkey_users_back(struct inode *ip)
-{
- struct task_struct *p, *found, *me = current;
- DECLARE_WAITQUEUE(wait, me);
-
- while (1) {
- found = NULL;
- read_lock(&tasklist_lock);
- for_each_task(p)
- if (p != me && !(p->mosix.dflags & DREMOTE) &&
- task_maps_ip(p, ip)) {
- task_lock(p);
- p->mosix.stay |= DSTAY_FOR_MONKEY;
- task_unlock(p);
- if (p->mosix.dflags & DDEPUTY) {
- tell_process(p, DREQ_HOMEWAKE);
- wake_up_mosix(p);
- if (!found) {
- found = p;
- get_task_struct(p);
- }
- }
- }
- if (!found) {
- read_unlock(&tasklist_lock);
- /* VMODIFIED is needed against a nearly-impossible
- * REMOTE race, when ip is modified, then unmonkied
- * and a process migrates there even before the
- * previous completed exiting:
- */
- OPENMOSIX_VMODIFIED(ip);
- return;
- }
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(mos_to_waitp(&found->mosix), &wait);
- read_unlock(&tasklist_lock);
- schedule();
- remove_wait_queue(mos_to_waitp(&found->mosix), &wait);
- set_current_state(TASK_RUNNING);
- free_task_struct(found);
- }
-}
-
-void
-mosix_no_longer_monkey(struct inode *ip)
-{
- struct task_struct *p;
-
- read_lock(&tasklist_lock);
- for_each_task(p)
- if (!(p->mosix.dflags & (DREMOTE | DDEPUTY)) && task_maps_ip(p,
ip)) {
- tell_process(p, DREQ_CHECKSTAY);
- wake_up_mosix(p);
- }
- read_unlock(&tasklist_lock);
-}
/*
* caller is responsible to down_[read|write](¤t->mm->mmap_sem)
@@ -824,8 +765,6 @@
ip = mpnt->vm_file->f_dentry->d_inode;
mode = ip->i_mode;
- if (ip->i_mapping->i_mmap_shared)
- stay |= DSTAY_FOR_MONKEY;
if (S_ISCHR(mode) || S_ISFIFO(mode) ||
S_ISSOCK(mode))
stay |= DSTAY_FOR_DEV;
@@ -917,8 +856,6 @@
{
if ((p->mosix.dflags & (DPASSING | DREMOTE)) == DPASSING)
return;
- if (p->mosix.held_files)
- mosix_clear_all_held_files(p);
if (!(p->mosix.dflags & DDEPUTY))
mosix_pre_dropping_mm(p, p->mm);
task_lock(p);
@@ -940,8 +877,6 @@
p->mosix.stay &= ~(DSTAY_PER_MM | DSTAY_FOR_CLONE);
task_unlock(p);
p->mosix.pages_i_bring = 0;
- if (p->mosix.held_files)
- mosix_clear_all_held_files(p);
}
int
diff -Naur linux-2.4.26-om1/hpc/Makefile linux-2.4.26-om1-o/hpc/Makefile
--- linux-2.4.26-om1/hpc/Makefile 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/Makefile 2006-05-07 17:56:02.000000000 +0530
@@ -20,7 +20,7 @@
obj-y := alternate.o auto_syscalls.o balance.o comm.o config.o decay.o \
deputy.o div.o export.o freemem.o init.o info.o kernel.o load.o \
mig.o hpcadmin.o hpcproc.o prequest.o remote.o rinode.o \
- service.o syscalls.o ucache.o badops.o
+ service.o syscalls.o ucache.o badops.o mig_shm.o shm_comm.o
shm_filemap.o
obj-$(CONFIG_MOSIX_DFSA) += dfsa.o
diff -Naur linux-2.4.26-om1/hpc/mig.c linux-2.4.26-om1-o/hpc/mig.c
--- linux-2.4.26-om1/hpc/mig.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/mig.c 2006-05-07 17:56:02.000000000 +0530
@@ -215,7 +215,9 @@
if (SHOW_MIGRATIONS)
printk("Weeeeeeeee.....\n");
#endif /* SHOW_MIGRATIONS */
+
kickstart();
+
panic("kickstart returned");
/*NOTREACHED*/ failed:
if (load_came_in) {
@@ -254,7 +256,6 @@
{
struct task_struct *p = current;
int error;
-
if (!PE)
return (whereto && whereto != GOBACKHOME &&
whereto != MUSTGOHOME ? -EDIST : 0);
@@ -278,7 +279,7 @@
return (0);
}
#endif /* CONFIG_MOSIX_CHEAT_MIGSELF */
- if (whereto && ((p->mosix.stay & DSTAY) || !mos_to_net(whereto, 0)))
+ if (whereto && ((p->mosix.stay & DSTAY) || !mos_to_net(whereto, 0)))
return (-EDIST);
spin_lock_irq(&runqueue_lock);
@@ -477,9 +478,6 @@
int error;
int omigpages;
- if (!p->mosix.held_files && (error = mosix_rebuild_file_list()))
- return (error);
-
lock_mosix();
write_lock_irq(&tasklist_lock);
p->mosix.remote_caps = current->cap_effective;
@@ -500,7 +498,7 @@
unlock_mosix();
p->mosix.deputy_regs = ALL_REGISTERS;
p->mosix.pass_regs = 0;
-
+
if (!(mlink = comm_open(whereto, 0, comm_connect_timo))) {
error = -EDIST;
goto failed;
@@ -591,10 +589,6 @@
#endif /*SHOW_MIGRATIONS */
end_coming_in(0);
current->mosix.pages_i_bring = 0;
- if (p->mosix.dflags & DDELAYHELD) {
- p->mosix.dflags &= ~DDELAYHELD;
- mosix_rebuild_file_list();
- }
return (0);
}
@@ -715,8 +709,6 @@
stop_storing_common_ps_info();
flush_read_cache();
free_ucache();
- if (m->stay & DSTAY_FOR_MONKEY)
- mosix_check_for_freedom_to_move();
} else {
if (m->contact) {
comm_close(m->contact);
@@ -772,6 +764,7 @@
m.uniq = ip->i_unique;
m.isize = ip->i_size;
m.nopage = vma->vm_ops->nopage;
+
}
} else {
m.fp = NULL;
@@ -962,9 +955,9 @@
comm_migration_mode(1);
neutralize_my_load(1); /* don't count me: I'm going to disappear */
if (mig_send_mm_stats() || mig_send_mm_areas() ||
- (credit = mig_send_pages()) < 0 ||
- (current->used_math && mig_send_fp()) ||
- (current->mm->context.ldt && mig_send_ldt()) ||
+ (credit = mig_send_pages()) < 0 ||
+ (current->used_math && mig_send_fp()) ||
+ (current->mm->context.ldt && mig_send_ldt()) ||
mig_send_misc(credit)) {
comm_send(MIG_NOT_COMING, NULL, 0, NULL, 0, 0);
comm_migration_mode(0);
@@ -1000,6 +993,12 @@
/* unconvert prot+flags: */
flags = MAP_FIXED | MAP_PRIVATE;
+
+ if(m->flags & VM_SHARED) {
+ flags &= ~(MAP_PRIVATE);
+ flags|=MAP_SHARED;
+ }
+
prot = 0;
if (m->flags & VM_GROWSDOWN)
flags |= MAP_GROWSDOWN;
@@ -1481,7 +1480,6 @@
if (to > 0)
return (passto(to, 0) ?
(mos_to_net(to, NULL) ? -ENETUNREACH : -ENXIO) : 0);
-
switch (to) {
case DM_GOBACKHOME:
return (passto(GOBACKHOME, 0) ? -EDIST : 0);
diff -Naur linux-2.4.26-om1/hpc/mig_shm.c linux-2.4.26-om1-o/hpc/mig_shm.c
--- linux-2.4.26-om1/hpc/mig_shm.c 1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/mig_shm.c 2006-05-08 10:48:35.000000000 +0530
@@ -0,0 +1,744 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/locks.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/blkdev.h>
+#include <linux/file.h>
+#include <linux/swapctl.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/iobuf.h>
+#include<asm/system.h>
+ +#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/mman.h>
+ +#include <linux/highmem.h>
+#include<linux/vmalloc.h>
+
+
+#include<hpc/protocol.h>
+#include<hpc/mig_shm.h>
+#include<hpc/shm_pagemap.h>
+#include <linux/hpc.h>
+
+
+
+void invalidate(struct shm_page *shm_page,struct page *page,int write_access)
+{
+ + pte_t pte; + pte_t *page_table;
+ unsigned long address;
+ struct vm_area_struct *vma;
+ struct mm_struct *mm;
+ struct address_space *mapping = page->mapping;
+ struct task_struct *p = current;
+ int i=1;
+
+ lock_page(page);
+ + spin_lock(&shm_page->shm_lock);
+
+ if(!(p->mosix.dflags & DDEPUTY) && !(p->mosix.dflags & DREMOTE) &&
!(shm_page->state & AT_HOME)) {
+ if(write_access) {
+ shm_page->state &= ~STATE_MASK;
+ shm_page->state |= IDLE;
+ }
+ else {
+ shm_page->state &= ~STATE_MASK;
+ shm_page->state |= SHARED;
+ }
+ }
+
+ spin_unlock(&shm_page->shm_lock);
+ + if((page->mapping == shm_page->mapping) && (page->index ==
shm_page->index)) {
+ + spin_lock(&mapping->i_shared_lock);
+ vma = mapping->i_mmap_shared;
+
+ while(vma) {
+ if(page->index >= vma->vm_pgoff) {
+ address = ((page->index - vma->vm_pgoff) <<
PAGE_CACHE_SHIFT) + vma->vm_start;
+ if(address < vma->vm_end ) {
+ mm = vma->vm_mm;
+ spin_lock(&mm->page_table_lock);
+ page_table =
pte_offset(pmd_offset(pgd_offset(mm,address),address),address);
+ if(pte_present(*page_table) && (i ||
!pte_write(*page_table))) {
+ flush_cache_page(vma, address);
+ pte =
ptep_get_and_clear(page_table);
+ flush_tlb_page(vma, address);
+
+ if(!write_access)
+
set_pte(page_table,pte_wrprotect(pte));
+ else {
+ mm->rss--;
+
page_cache_release(page);
+ }
+
+ if (pte_dirty(pte))
+ set_page_dirty(page);
+ } +
spin_unlock(&mm->page_table_lock); + }
+ }
+ vma = vma->vm_next_share; + if(!vma
&& i--)
+ vma = mapping->i_mmap;
+ }
+ + spin_unlock(&mapping->i_shared_lock);
+ }
+/*
+ * else + *
+ * printk("{trancated:%u %u}",page->mapping,page->index);
+ */
+
+ + if(write_access && !(p->mosix.dflags & DREMOTE) && !(p->mosix.dflags &
DDEPUTY) && !(shm_page->state & AT_HOME)) {
+ page->shm_page = NULL;
+ shm_pagecache_release(shm_page);
+ + ClearPageUptodate(page);
+ ClearPageDirty(page); + }
+
+ unlock_page(page);
+ return;
+}
+ +
+static int send_upgrade(struct shm_page *shm_page,struct page *page)
+{
+ int res = 1;
+
+ lock_page(page);
+ + if((shm_page->state & STATE_MASK) == SHARED) {
+ res = remote_upgrade(shm_page);
+ if(!res) {
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~SHARED;
+ shm_page->owner = PE;
+ shm_page->state |= EXCLUSIVE;
+ spin_unlock(&shm_page->shm_lock);
+ } else if(res == 2) {
+ shm_page->state |= PERM_ERR;
+ printk(KERN_ERR "A shared page here is invalid: Reboot
!\n");
+ }
+ } else if((shm_page->state & STATE_MASK) == EXCLUSIVE &&
((shm_page->owner == PE) || (shm_page->owner == 0))) + res = 0;
+
+ unlock_page(page);
+ return res;
+}
+
+static struct page *get_exc_rem(struct vm_area_struct *vma,unsigned long
address,struct shm_page *shm_page)
+{
+ struct page *page;
+ int res = 0;
+ + page = vma->vm_ops->nopage(vma,address,WITH_WRITE_ACC);
+
+ if(!page || (page == NOPAGE_OOM) || page == PAGE_BUSY)
+ return page;
+
+ spin_lock(&shm_page->shm_lock);
+ + if(!(res = ((shm_page->state & STATE_MASK) == IDLE)) &&
((shm_page->state & STATE_MASK) == SHARED)) {
+ spin_unlock(&shm_page->shm_lock);
+ res = send_upgrade(shm_page,page);
+ goto out;
+ }
+
+ spin_unlock(&shm_page->shm_lock);
+
+out: if(!res)
+ return page;
+ else {
+ page_cache_release(page);
+ if(res == 1) + return PAGE_BUSY;
+ else
+ return NULL;
+ }
+}
+
+ +static struct page *get_page_exc_in_exc(struct vm_area_struct *vma, unsigned
long address,struct shm_page *shm_page)
+{
+ struct page *page = NULL;
+
+ switch(current->mosix.dflags & (DDEPUTY|DREMOTE)) {
+ + case DREMOTE :
+
+ spin_unlock(&shm_page->shm_lock);
+ page = get_exc_rem(vma,address,shm_page);
+
+ break;
+
+ case DDEPUTY:
+
+ if(!vma) goto AS_HERE;
+
+ shm_page->state &= ~EXCLUSIVE;
+ shm_page->state |= BUSY_EXCLUSIVE;
+ spin_unlock(&shm_page->shm_lock);
+
+ if(!PE || (shm_page->owner == 0) || (shm_page->owner ==
PE)) {
+ page = vma->vm_ops->nopage(vma,address,0);
+ if((page == NOPAGE_OOM )|| !page) {
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~BUSY_EXCLUSIVE;
+ shm_page->state |= EXCLUSIVE;
+ spin_unlock(&shm_page->shm_lock);
+ return page;
+ }
+ invalidate(shm_page,page,1);
+ shm_pagecache_get(shm_page);
+ } else {
+ page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+ +
if(shm_send_message(shm_page->owner,shm_page,page,FORWARD_REQUEST_WRITE)) +
goto here;
+
+ SetPageUptodate(page);
+ set_page_dirty(page);
+ unlock_page(page);
+ }
+
+ vma->vm_end = 0;
+ vma->vm_start = 0;
+
+ break;
+
+ AS_HERE:
+ default:
+ if(!PE || (shm_page->owner == 0) || (shm_page->owner ==
PE)) {
+ spin_unlock(&shm_page->shm_lock);
+ if(vma)
+ page = vma->vm_ops->nopage(vma,
address,0);
+ } else {
+ + shm_page->state &= ~EXCLUSIVE;
+ shm_page->state |= BUSY_EXCLUSIVE;
+
+ spin_unlock(&shm_page->shm_lock);
+ + page = find_or_create_page(shm_page->mapping,
+
shm_page->index,GFP_NOFS);
+ + shm_page->next = shm_page->prev = PE;
+ shm_page->next_addr = shm_page->prev_addr =
shm_page;
+
+
+
if(shm_send_message(shm_page->owner,shm_page,page,FORWARD_REQUEST_WRITE)) {
+ here : unlock_page(page);
+ page_cache_release(page);
+ printk(KERN_ERR "Data Loss : What
happened to node %d ,Reboot this node\n",shm_page->owner);
+ spin_lock(&shm_page->shm_lock);
+ shm_page->owner = PE;
+ shm_page->state &= ~BUSY_EXCLUSIVE;
+ shm_page->state |=
(EXCLUSIVE|PERM_ERR);
+ spin_unlock(&shm_page->shm_lock);
+ shm_pagecache_release(shm_page);
+ return NULL;
+ } +
+ SetPageUptodate(page);
+ set_page_dirty(page);
+ unlock_page(page);
+
+ shm_page->owner = PE;
+ + spin_lock(&shm_page->shm_lock);
+ shm_page->state |= EXCLUSIVE;
+ shm_page->state &= ~BUSY_EXCLUSIVE;
+ spin_unlock(&shm_page->shm_lock);
+
+ shm_pagecache_release(shm_page);
+ } + }
+ return page;
+} +
+static struct page *get_page_exc_in_shared(struct vm_area_struct *vma,
unsigned long address,struct shm_page *shm_page)
+{
+ struct page *page = NULL;
+
+ switch(current->mosix.dflags & (DDEPUTY|DREMOTE)) {
+
+ case DREMOTE :
+
+ spin_unlock(&shm_page->shm_lock);
+ page = get_exc_rem(vma,address,shm_page);
+
+ break;
+
+ case DDEPUTY:
+ + if(!vma) goto AS_HERE;
+
+ if(shm_page->state & DROPPING) {
+ page = PAGE_BUSY;
+ spin_unlock(&shm_page->shm_lock);
+ } else {
+ shm_page->state &= ~SHARED;
+ shm_page->state |= BUSY_EXCLUSIVE;
+
+ spin_unlock(&shm_page->shm_lock);
+ + + page = vma->vm_ops->nopage(vma,address,0);
+ + if((page == NOPAGE_OOM) || !page) {
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &=
~BUSY_EXCLUSIVE;
+ shm_page->state |= SHARED;
+
spin_unlock(&shm_page->shm_lock);
+ return page;
+ }
+ + invalidate(shm_page,page,1); + +
+ vma->vm_start = 0;
+ vma->vm_end = 0;
+
+ if(PE && (shm_page->prev != PE) &&
(shm_page->prev != 0)) { + vma->vm_end =
shm_page->next;
+ vma->vm_start = (unsigned
long)shm_page->next_addr;
+ shm_page->next =
current->mosix.whereami;
+ shm_page->next_addr = (struct shm_page
*)vma->vm_flags;
+
if(shm_send_message(shm_page->prev,shm_page,page,DROP_NEXT)) {
+ printk("reader loop broken
because of %d ! reboot all",shm_page->prev);
+ shm_page->state |= UPGRADE_ERR;
+ }
+ }
+ }
+
+ break;
+
+ AS_HERE:
+ default:
+ if(shm_page->state & DROPPING) {
+ spin_unlock(&shm_page->shm_lock);
+ page = PAGE_BUSY;
+ } else {
+ shm_page->owner = PE;
+ shm_page->state |= DROPPING;
+ spin_unlock(&shm_page->shm_lock);
+ + if(vma)
+ page =
vma->vm_ops->nopage(vma,address,0);
+ + if(PE && (shm_page->next != PE) &&
(shm_page->next != 0)) +
if(shm_send_message(shm_page->next,shm_page,page,INVALIDATE))
+ shm_page->state |= UPGRADE_ERR;
+
+ shm_page->next = shm_page->prev = PE;
+ shm_page->next_addr = shm_page->prev_addr =
shm_page;
+
+ spin_lock(&shm_page->shm_lock);
+ + shm_page->state &= ~SHARED;
+ shm_page->state |= EXCLUSIVE;
+ shm_page->state &= ~DROPPING;
+ + spin_unlock(&shm_page->shm_lock);
+ + shm_pagecache_release(shm_page);
+ }
+
+ break;
+
+ }
+ return page;
+}
+
+static struct page *get_page_shared_in_exc(struct vm_area_struct *vma,
unsigned long address,struct shm_page *shm_page)
+{
+ struct page *page = PAGE_BUSY;
+
+ switch(current->mosix.dflags & (DDEPUTY|DREMOTE)) {
+ case DREMOTE:
+ + spin_unlock(&shm_page->shm_lock);
+ page = vma->vm_ops->nopage(vma,address,WITH_READ_ACC);
+ break;
+
+ case DDEPUTY:
+ + if(!vma) goto AS_HERE;
+
+ shm_page->prev = shm_page->next =
current->mosix.whereami;
+ shm_page->prev_addr = shm_page->next_addr = (struct
shm_page *)vma->vm_flags;
+
+ if(!PE || (shm_page->owner == 0) || (shm_page->owner ==
PE)) {
+ shm_page->state &= ~EXCLUSIVE;
+ shm_page->state |= (SHARED|DROPPING);
+ spin_unlock(&shm_page->shm_lock);
+ + page = vma->vm_ops->nopage(vma,address,0);
+ if((page == NOPAGE_OOM) || (!page)) {
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~(SHARED|DROPPING);
+ shm_page->state |= EXCLUSIVE;
+ spin_unlock(&shm_page->shm_lock);
+ return page;
+ }
+ + vma->vm_end = PE;
+ vma->vm_start =(unsigned long) shm_page;
+
+ invalidate(shm_page,page,0);
+ shm_pagecache_get(shm_page);
+ } else {
+ shm_page->state &= ~EXCLUSIVE;
+ shm_page->state |= BUSY_SHARED;
+ spin_unlock(&shm_page->shm_lock);
+ + vma->vm_end = shm_page->owner;
+ vma->vm_start = (unsigned
long)shm_page->rem_shm_page_addr;
+ + shm_page->next = shm_page->owner;
+ shm_page->next_addr =
shm_page->rem_shm_page_addr;
+ + page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+
+ if(shm_send_message(shm_page->owner,
shm_page,page, FORWARD_REQUEST_READ)) + goto
here;
+
+ SetPageUptodate(page);
+ set_page_dirty(page);
+ unlock_page(page);
+
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~ BUSY_SHARED;
+ shm_page->state |= (SHARED|DROPPING);
+ spin_unlock(&shm_page->shm_lock);
+ }
+
+ break;
+
+ AS_HERE:
+ default:
+
+ if(!PE || (shm_page->owner == 0) || (shm_page->owner ==
PE)) {
+ spin_unlock(&shm_page->shm_lock);
+ if(vma)
+ page =
vma->vm_ops->nopage(vma,address,0);
+ } else {
+ shm_page->state &= ~EXCLUSIVE;
+ shm_page->state |= BUSY_SHARED;
+ spin_unlock(&shm_page->shm_lock);
+
+ shm_page->prev = shm_page->next =
shm_page->owner;
+ shm_page->prev_addr = shm_page->next_addr =
shm_page->rem_shm_page_addr;
+
+ page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+ +
if(shm_send_message(shm_page->owner,shm_page,page,FORWARD_REQUEST_READ)) {
+ here: unlock_page(page);
+ page_cache_release(page);
+ printk(KERN_INFO "Data Loss : What
happened to node %d ? Reboot this node\n",shm_page->owner);
+ shm_page->owner = PE;
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~BUSY_SHARED;
+ shm_page->state |=
(EXCLUSIVE|PERM_ERR);
+ spin_unlock(&shm_page->shm_lock);
+ shm_pagecache_release(shm_page);
+ return NULL;
+ } + +
SetPageUptodate(page);
+ set_page_dirty(page);
+ unlock_page(page);
+ + spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~BUSY_SHARED;
+ shm_page->state |= SHARED;
+ spin_unlock(&shm_page->shm_lock);
+ }
+
+ break;
+ }
+ return page;
+}
+ +static struct page *get_page_shared_in_shared(struct vm_area_struct *vma,
unsigned long address,struct shm_page *shm_page)
+{
+ struct page *page = PAGE_BUSY;
+ struct task_struct *p = current;
+ + if(p->mosix.dflags & DDEPUTY) {
+
+ if(shm_page->state & DROPPING) {
+ spin_unlock(&shm_page->shm_lock);
+ return(page);
+ }
+
+ shm_page->state |= DROPPING;
+ spin_unlock(&shm_page->shm_lock);
+
+ page = vma->vm_ops->nopage(vma,address,0);
+ if((page == NOPAGE_OOM) || !page) {
+ shm_page->state &= ~DROPPING;
+ return page;
+ }
+ if(PE && (shm_page->prev != PE) && (shm_page->prev != 0)) {
+
+ vma->vm_end = shm_page->next;
+ vma->vm_start = (unsigned long)shm_page->next_addr;
+
+ shm_page->next = p->mosix.whereami;
+ shm_page->next_addr = (struct shm_page *)vma->vm_flags;
+
+
if(shm_send_message(shm_page->prev,shm_page,NULL,DROP_NEXT)) {
+ printk(KERN_ERR "node %d down:reader loop
broken,reboot all !\n",shm_page->prev); +
shm_page->next = vma->vm_end;
+ shm_page->next_addr = (struct shm_page
*)vma->vm_start;
+
+
shm_send_message(shm_page->next,shm_page,NULL,INVALIDATE);
+
+ shm_page->owner = shm_page->next =
shm_page->prev =PE;
+ shm_page->next_addr = shm_page->prev_addr =
shm_page;
+
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~(DROPPING|SHARED);
+ shm_page->state |= (EXCLUSIVE|UPGRADE_ERR);
+ spin_unlock(&shm_page->shm_lock);
+
+ page_cache_release(page);
+ shm_pagecache_release(shm_page);
+ return NULL;
+ }
+
+ shm_page->next = vma->vm_end;
+ shm_page->next_addr = (struct shm_page *)
vma->vm_start;
+
+ vma->vm_start = (unsigned long)shm_page->prev_addr;
+ vma->vm_end = shm_page->prev;
+
+ } else {
+ vma->vm_start = (unsigned long)shm_page;
+ vma->vm_end = PE;
+ shm_page->next_addr = (struct shm_page
*)vma->vm_flags;
+ shm_page->next = p->mosix.whereami;
+ }
+
+ shm_page->prev = current->mosix.whereami; +
shm_page->prev_addr = (struct shm_page *)vma->vm_flags;
+
+ } else { + + spin_unlock(&shm_page->shm_lock);
+ page = vma->vm_ops->nopage(vma,address,(p->mosix.dflags &
DREMOTE) ? WITH_READ_ACC:0);
+
+ }
+ return page;
+}
+
+
+
+
+static struct page *send_page_exclusive(struct vm_area_struct *vma, unsigned
long address,
+ struct shm_page
*shm_page,int write_access)
+{
+ struct page *page = PAGE_BUSY;
+
+ spin_lock(&shm_page->shm_lock);
+
+ if((current->mosix.dflags & DDEPUTY) && (shm_page->writers ||
shm_page->readers)) {
+ spin_unlock(&shm_page->shm_lock);
+ goto out;
+ }
+
+ switch(shm_page->state & STATE_MASK) {
+
+ case EXCLUSIVE:
+ case IDLE: + if((write_access == 11) && (!PE
|| ((shm_page->state & STATE_MASK) == EXCLUSIVE))) {
+ spin_unlock(&shm_page->shm_lock);
+ return NULL;
+ }
+ + page = get_page_exc_in_exc(vma, address, shm_page);
+
+ break;
+
+ case SHARED:
+ page = get_page_exc_in_shared(vma, address, shm_page);
+ break;
+ default:
+ spin_unlock(&shm_page->shm_lock);
+ break;
+ }
+
+out:
+ return page;
+}
+
+static struct page *send_page_shared(struct vm_area_struct *vma,unsigned long
address,struct shm_page *shm_page)
+{
+ struct page *page = PAGE_BUSY;
+
+ spin_lock(&shm_page->shm_lock);
+ if((current->mosix.dflags & DDEPUTY) && ((shm_page->writers) ||
(shm_page->state & UPGRADE_ERR)) ) {
+ if(shm_page->state & UPGRADE_ERR)
+ page = NULL;
+ spin_unlock(&shm_page->shm_lock);
+ goto out;
+ } +
+ switch(shm_page->state & STATE_MASK) {
+
+ case EXCLUSIVE:
+ case IDLE:
+ + page = get_page_shared_in_exc(vma,address,shm_page);
+
+ break;
+ case SHARED:
+ page =
get_page_shared_in_shared(vma,address,shm_page);
+ break;
+ default:
+ spin_unlock(&shm_page->shm_lock);
+ break;
+ }
+
+out: + return page;
+}
+
+void wait_here() +{
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(5*HZ);
+}
+ +struct page *get_nopage(struct vm_area_struct *vma, unsigned long
address,struct shm_page **shm_page,int write_access)
+{
+ struct page *new_page = NULL;
+ struct task_struct *p = current;
+ struct address_space *mapping =
vma->vm_file->f_dentry->d_inode->i_mapping;
+ unsigned long index = ((address - vma->vm_start) >> PAGE_CACHE_SHIFT)
+ vma->vm_pgoff;
+
+ *shm_page = find_or_create_shm_page(mapping,index);
+ if((*shm_page)->state & PERM_ERR) + goto out;
+
+ while(1) {
+ if((write_access == 1) || (write_access == 11))
+ new_page=send_page_exclusive(vma, address & PAGE_MASK,
*shm_page, write_access);
+ else if(write_access == 0 || write_access == 2) +
new_page=send_page_shared(vma, address & PAGE_MASK, *shm_page);
+
+ if((new_page != PAGE_BUSY) || (p->mosix.dflags & DDEPUTY))
+ break;
+ else
+ wait_here();
+ }
+
+out: if((new_page == NULL || new_page == NOPAGE_OOM || new_page == PAGE_BUSY
|| (write_access == 2)) && write_access != 11) {
+ shm_pagecache_release(*shm_page);
+ *shm_page = NULL;
+ }
+
+ return new_page;
+}
+
+int
+get_pages(struct address_space *mapping,loff_t offset,size_t count,int writer)
+{
+ struct shm_page *shm_page;
+ struct page *page=NULL;
+ unsigned long index = (offset >> PAGE_CACHE_SHIFT),
+ end = ((offset+count) >> PAGE_CACHE_SHIFT);
+ + for(;index <= end; index++) {
+
+ shm_page = find_or_create_shm_page(mapping,index);
+
+ if(shm_page->state & PERM_ERR)
+ return (index + 1); +
+ spin_lock(&shm_page->shm_lock);
+ + if(writer)
+ shm_page->writers++;
+ else
+ shm_page->readers++;
+ + + again: switch(shm_page->state & STATE_MASK) { +
case EXCLUSIVE:
+ if(PE && (shm_page->owner != PE) &&
(shm_page->owner != 0)) {
+ if(writer) {
+ if(shm_page->readers) {
+ page = PAGE_BUSY;
+
spin_unlock(&shm_page->shm_lock);
+ }
+ else
+ page =
get_page_exc_in_exc(NULL,0,shm_page);
+ } else
+ page =
get_page_shared_in_exc(NULL,0,shm_page);
+
+ if(page == PAGE_BUSY) +
goto here;
+ else if (page)
+ page_cache_release(page);
+ } else
+ spin_unlock(&shm_page->shm_lock);
+ break;
+
+ case SHARED:
+ if(!writer) {
+ spin_unlock(&shm_page->shm_lock);
+ break;
+ } else
if(!get_page_exc_in_shared(NULL,0,shm_page)) {
+ break;
+ } else +
goto here;
+ default:
+ spin_unlock(&shm_page->shm_lock);
+ here: wait_here();
+ spin_lock(&shm_page->shm_lock);
+ goto again;
+ }
+ }
+ return 0;
+}
+void +put_pages(struct address_space *mapping,loff_t offset,size_t count,int
writer,unsigned long end) +{
+
+ struct shm_page *shm_page;
+ unsigned long index = (offset >> PAGE_CACHE_SHIFT);
+ + if(!end--) + end = ((offset+count) >>
PAGE_CACHE_SHIFT);
+
+ for(;index <= end; index++) {
+ shm_page =
find_get_shm_page(mapping,index,shm_page_hash(mapping,index));
+ + spin_lock(&shm_page->shm_lock);
+ if(writer) + shm_page->writers--;
+ else
+ shm_page->readers--;
+ spin_unlock(&shm_page->shm_lock);
+ + shm_pagecache_release(shm_page);
+ shm_pagecache_release(shm_page);
+ }
+}
+ diff -Naur linux-2.4.26-om1/hpc/remote.c linux-2.4.26-om1-o/hpc/remote.c
--- linux-2.4.26-om1/hpc/remote.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/remote.c 2006-05-07 17:56:02.000000000 +0530
@@ -31,6 +31,8 @@
#include <linux/file.h>
#include <hpc/balance.h>
#include <hpc/dfsa.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
int
remote_wait(int expect, void **head, int *hlen)
@@ -109,10 +111,6 @@
remote_mprotect((struct mprotect_parameters_h *)
*head);
break;
- case DEP_LISTHOLD:
- comm_free(*head);
- error = remote_report_files();
- break;
case DEP_SETUPFRAME:
error =
remote_setup_frame((struct setupframe_parameters_h
@@ -471,22 +469,93 @@
bump_syscalls(); /* no accurate numbers, but it costs! */
wait_for_permission_to_continue();
}
+int
+remote_writepage(struct page *page)
+{
+ struct shm_page *shm_page;
+ int res;
+ shm_page = page->shm_page;
+
+ struct address_space *mapping = page->mapping;
+ unsigned long index = page->index;
+
+retry: if((shm_page->state & STATE_MASK) == IDLE)
+ goto out;
+
+ if((shm_page->state & STATE_MASK) == EXCLUSIVE) + res =
shm_send_message(page->mapping->host->u.remote_i.origin,shm_page,page,WRITE_BACK);
+ else + res =
shm_send_message(page->mapping->host->u.remote_i.origin,shm_page,page,DROP_PAGE);
+
+ if(res == 1) { + SetPageDirty(page); +
unlock_page(page);
+ wait_here();
+ lock_page(page);
+ if(mapping != page->mapping || index != page->index) +
goto out;
+
+ goto retry;
+ } else {
+ ClearPageDirty(page);
+ if(res)
+ printk(KERN_ERR "Comm loss: Reboot this and %d %d nodes
!\n",shm_page->next,shm_page->prev);
+
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~STATE_MASK;
+ shm_page->state |= IDLE; +
spin_unlock(&shm_page->shm_lock);
+
+ page->shm_page = NULL;
+ shm_pagecache_release(shm_page);
+ }
+
+out: unlock_page(page); + return(0);
+}
+
+int +remote_upgrade(struct shm_page *shm_page)
+{
+ struct upgrade_h u;
+ struct shm_page_ret_h r;
+
+ u.rem_shm_page_addr = shm_page->rem_shm_page_addr;
+ u.shm_page = shm_page;
+ int error;
+
+ if (!(error = remote_request(REM_UPGRADE, &u, sizeof (u), NULL, 0, 0,
+ (void **) &r, -sizeof (r)))) {
+ if((!(r.ret)) && (shm_page->prev != 0) && (shm_page->prev !=
PE)) +
shm_send_message(shm_page->next,shm_page,NULL,INVALIDATE);
+ error = r.ret;
+ }
+
+ absorb_deptime(r.deputytime);
+ return error;
+}
+
int
remote_readpage(struct file *fp, struct page *page)
{
- int error;
+ int error=0;
char *buffer = kmap(page);
struct bring_page_h b;
- struct page_ret_h r;
+ struct shm_page_ret_h r;
int dpagein = (current->mosix.dflags & DPAGEIN) ^ DPAGEIN;
struct task_struct *p = current;
-
+ struct shm_page *shm_page = page->shm_page;
+
if (!PageLocked(page))
PAGE_BUG(page);
+
b.fp = home_file(fp);
- b.offset = page->index << PAGE_CACHE_SHIFT;
+ b.offset = (page->index << PAGE_CACHE_SHIFT);
b.nopage = fp->f_dentry->d_inode->u.remote_i.nopage;
+ b.rem_shm_page_addr = shm_page; + b.access = (shm_page->state &
ACC_MASK);
+
if (p->mosix.rfreepages > 0)
p->mosix.rfreepages--;
else
@@ -498,28 +567,65 @@
p->mosix.dflags |= dpagein;
spin_unlock_irq(&runqueue_lock);
}
- if (!b.nopage) /* home rebooted, we should be dead anyway */
- error = -EIO;
+ + if (!b.nopage) /* home rebooted, we should be dead anyway */
+ error = -EIO;
else if (!(error = remote_request(REM_PAGE, &b, sizeof (b), NULL, 0, 0,
- (void **) &r, -sizeof (r))))
+ (void **) &r, -sizeof (r))))
error = r.ret;
- if (!error)
+
+ if (!error)
error = comm_copydata(buffer, PAGE_SIZE, 0);
- else if (error == -EFBIG) {
- memset(buffer, 0, PAGE_SIZE);
- error = 0;
- }
- if (error) {
+
+ if(!error) {
+ + spin_lock(&shm_page->shm_lock);
+
+ shm_page->owner = PE;
+
+ shm_page->state &= ~STATE_MASK;
+ shm_page->state |= ((b.access & WITH_WRITE_ACC) ? EXCLUSIVE :
SHARED);
+
+ spin_unlock(&shm_page->shm_lock);
+
+ shm_page->rem_shm_page_addr = r.rem_shm_page_addr;
+
+ shm_page->next = r.next;
+ shm_page->next_addr = r.next_addr;
+
+ if(b.access & WITH_WRITE_ACC) {
+ if(r.next_addr) +
if(shm_send_message(shm_page->next,shm_page,page,INVALIDATE))
+ printk(KERN_ERR "REBOOT ALL\n");
+ shm_page->next_addr = shm_page->prev_addr = shm_page;
+ shm_page->next = shm_page->prev = PE;
+ + } else {
+ shm_page->prev = r.prev;
+ shm_page->prev_addr = r.prev_addr;
+
shm_send_message(current->mosix.deppe,shm_page,NULL,DROP_PAGE_END);
+ }
+
+ SetPageUptodate(page);
+ set_page_dirty(page);
+ } else {
+
ClearPageUptodate(page);
- SetPageError(page);
- } else
- SetPageUptodate(page);
+ ClearPageDirty(page);
+ SetPageError(page);
+ page->shm_page = NULL;
+ shm_pagecache_release(shm_page);
+ }
+
+ shm_page->state &= ~ACC_MASK;
+
UnlockPage(page);
kunmap(page);
spin_lock_irq(&runqueue_lock);
p->mosix.dflags &= ~dpagein;
spin_unlock_irq(&runqueue_lock);
absorb_deptime(r.deputytime);
+
return (error);
}
@@ -658,28 +764,34 @@
}
} else
rf = NULL;
- /* unconvert prot+flags: */
- prot = 0;
- flags = MAP_PRIVATE;
- if (m->fixed)
- flags |= MAP_FIXED;
- if (m->flags & VM_GROWSDOWN)
- flags |= MAP_GROWSDOWN;
- if (m->flags & VM_DENYWRITE)
- flags |= MAP_DENYWRITE;
- if (m->flags & VM_EXECUTABLE)
- flags |= MAP_EXECUTABLE;
- if (m->flags & VM_READ)
- prot |= VM_READ;
- if (m->flags & VM_WRITE)
- prot |= VM_WRITE;
- if (m->flags & VM_EXEC)
- prot |= VM_EXEC;
+ prot = 0;
+ flags = MAP_PRIVATE;
+ if(m->flags & VM_SHARED) {
+ flags &= ~(MAP_PRIVATE);
+ flags|=MAP_SHARED;
+ } + if (m->fixed)
+ flags |= MAP_FIXED;
+ if (m->flags & VM_GROWSDOWN)
+ flags |= MAP_GROWSDOWN;
+ if (m->flags & VM_DENYWRITE)
+ flags |= MAP_DENYWRITE;
+ if (m->flags & VM_EXECUTABLE)
+ flags |= MAP_EXECUTABLE;
+ if (m->flags & VM_READ)
+ prot |= PROT_READ;
+ if (m->flags & VM_WRITE)
+ prot |= PROT_WRITE;
+ if (m->flags & VM_EXEC)
+ prot |= PROT_EXEC;
+
if (m->flags & VM_MAYSHARE)
current->mosix.dirty_bits |= MMAP_MAYSHARE;
+
result = do_mmap_pgoff(rf, m->addr, m->len, prot, flags, m->pgoff);
+
if (m->flags & VM_MAYSHARE)
- current->mosix.dirty_bits &= ~MMAP_MAYSHARE;
+ current->mosix.dirty_bits &= ~MMAP_MAYSHARE;
if (rf && !IS_ERR((const void *) result)) {
int pages = (m->len + PAGE_SIZE - 1) / PAGE_SIZE;
@@ -688,8 +800,9 @@
current->mosix.rfreepages += pages;
}
if (m->flags & VM_READHINTMASK)
- sys_madvise(m->addr, m->len, (m->flags & VM_SEQ_READ) ?
- MADV_RANDOM : MADV_SEQUENTIAL);
+ sys_madvise(m->addr, m->len, (m->flags & VM_SEQ_READ) ?
+ MADV_RANDOM : MADV_SEQUENTIAL);
+
err:
if (rf)
fput(rf);
diff -Naur linux-2.4.26-om1/hpc/rinode.c linux-2.4.26-om1-o/hpc/rinode.c
--- linux-2.4.26-om1/hpc/rinode.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/rinode.c 2006-05-07 17:56:02.000000000 +0530
@@ -10,14 +10,16 @@
#include <hpc/protocol.h>
#include <hpc/comm.h>
#include <linux/hpc.h>
+#include <linux/locks.h>
#include <linux/smp_lock.h>
#include <linux/file.h>
#include <linux/dcache.h>
#include <linux/slab.h>
#include <hpc/routines.h>
#include <hpc/debug.h>
-
+#include <hpc/mig_shm.h>
/* REMOTE section: */
+//extern int remote_writepage(struct file*,struct page*);
spinlock_t rinode_list_lock = SPIN_LOCK_UNLOCKED;
@@ -33,7 +35,6 @@
static struct dentry_operations remote_dentry_ops = {
.d_delete = remote_dentry_delete,
- .d_iput = remote_dentry_iput
};
static struct file_operations remote_file_operations = {
@@ -41,19 +42,21 @@
};
struct address_space_operations remote_aops = {
+ .writepage = remote_writepage,
.readpage = remote_readpage,
};
-void
-invalidate_old_remote_pages(struct inode *ip)
+
+static
+struct inode *hpc_new_inode(struct super_block *sb)
{
- down(&ip->i_sem);
- /* we prefer "invalidate_inode_pages",
- but it does not work on locked pages */
- truncate_inode_pages(ip->i_mapping, 0);
- up(&ip->i_sem);
+ struct inode *inode = new_inode(sb);
+ if(inode)
+ insert_inode_hash(inode);
+ return (inode);
}
+
struct file *
get_remote_file(int origin, struct file *fpr, struct dentry *dpr, uint64_t
uniq,
off_t isize, nopage_t nopage)
@@ -80,6 +83,7 @@
}
if (!(f = get_empty_filp()))
return (NULL);
+
spin_lock(&dcache_lock);
spin_lock(&rinode_list_lock);
for (d = rinode_list; d; d = next_entry(d)) {
@@ -99,23 +103,29 @@
spin_unlock(&dcache_lock);
if (to_iput)
iput(to_iput);
+
if (to_dput)
dput(to_dput);
- if (cng)
- invalidate_old_remote_pages(ip);
+
f->f_dentry = d;
f->f_op = &remote_file_operations;
- f->f_mode = FMODE_READ;
+ f->f_mode = FMODE_READ|FMODE_WRITE;
home_file(f) = fpr;
+
+ shm_send_message(current->mosix.deppe,(struct shm_page
*)fpr,NULL,GET_FILE);
+
return (f);
}
}
spin_unlock(&rinode_list_lock);
spin_unlock(&dcache_lock);
- if (!(ip = new_inode(&bad_super_block))) {
+
+ if (!(ip = hpc_new_inode(&bad_super_block))) {
put_filp(f);
return (NULL);
}
+
+
ip->i_mode = S_IFREG;
ip->u.remote_i.origin = origin;
ip->u.remote_i.dp = dpr;
@@ -124,8 +134,9 @@
ip->i_size = isize;
ip->i_fop = &remote_file_operations;
ip->i_mapping->a_ops = &remote_aops;
- if (!(d = d_alloc(NULL, &(const struct qstr) {
- "/", 1, 0}))) {
+ if (!(d = d_alloc(NULL, &(const struct qstr) {
+ "/", 1, 0 } ))) {
+
put_filp(f);
iput(ip);
return (NULL);
@@ -150,10 +161,11 @@
rinode_list = d;
f->f_dentry = d;
f->f_op = &remote_file_operations;
- f->f_mode = 1;
+ f->f_mode = FMODE_READ|FMODE_WRITE;
home_file(f) = fpr;
spin_unlock(&rinode_list_lock);
spin_unlock(&dcache_lock);
+ shm_send_message(current->mosix.deppe,(struct shm_page
*)fpr,NULL,GET_FILE);
return (f);
}
@@ -179,14 +191,7 @@
spin_unlock(&rinode_list_lock);
return (1);
}
-
-static void
-remote_dentry_iput(struct dentry *dp, struct inode *ip)
-{
- invalidate_old_remote_pages(ip);
- iput(ip);
-}
-
+
struct vm_operations_struct rinode_mmap = {
.nopage = filemap_nopage,
};
@@ -194,393 +199,6 @@
static int
mosix_remote_file_mmap(struct file *file, struct vm_area_struct *vma)
{
- if (vma->vm_flags & VM_SHARED)
- panic("REMOTE VM_SHARED mmap");
vma->vm_ops = &rinode_mmap;
return (0);
}
-
-int
-remote_report_files(void)
-{
- struct vm_area_struct *vma, *vmb;
- struct mm_struct *mm = current->mm;
- struct file **fp = NULL;
- int n = 0;
- int result;
-
- down_read(&mm->mmap_sem);
- for (vma = mm->mmap; vma; vma = vma->vm_next)
- if (vma->vm_file) {
- for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next)
- if (vmb->vm_file == vma->vm_file)
- break;
- if (vmb == vma)
- n++;
- }
- up_read(&mm->mmap_sem);
- if (n && !(fp = kmalloc(n * sizeof (struct file *), GFP_KERNEL)))
- n = -EAGAIN;
- else {
- down_read(&mm->mmap_sem);
- for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next)
- if (vma->vm_file) {
- for (vmb = mm->mmap; vmb != vma;
- vmb = vmb->vm_next)
- if (vmb->vm_file == vma->vm_file)
- break;
- if (vmb == vma)
- fp[n++] = home_file(vma->vm_file);
- }
- up_read(&mm->mmap_sem);
- }
- result = comm_send(DEP_LISTHOLD | REPLY, &n, sizeof (int),
- fp, n > 0 ? n * sizeof (struct file *) : 0, 0);
- if (n > 0)
- kfree(fp);
- return (result);
-}
-
-void
-rinode_flush_files(int pe)
-{
- struct dentry *dp;
- struct inode *ip;
-
- loop:
- spin_lock(&rinode_list_lock);
- for (dp = rinode_list; dp; dp = next_entry(dp)) {
- ip = dp->d_inode;
- if (ip->u.remote_i.origin == pe && ip->u.remote_i.nopage) {
- ip->u.remote_i.dp = NULL;
- /* (the pointer is no good and any process
- * still using this inode is doomed anyway) */
- ip->u.remote_i.unique = 0xffffffffffffffffULL;
- ip->u.remote_i.nopage = NULL;
- spin_unlock(&rinode_list_lock);
- invalidate_old_remote_pages(ip);
- goto loop;
- }
- }
- spin_unlock(&rinode_list_lock);
-}
-
-/* DEPUTY section: */
-
-#define DEFAULT_ALLOCATION 10
-
-#define ALLOCATED_NEW 1
-#define ALLOCATED_NEW_AND_DENY 2
-#define ADDED_A_DENY 3
-#define FOUND_OLD 4
-
-int
-mosix_register_a_file(struct file *fp, int denywrite)
-{
- struct task_struct *p = current;
- int i, new;
- struct held_files *nh, *oh;
- struct mm_struct *mm;
-
- if (!p->mosix.held_allocated) {
- if ((mm = p->mm) && atomic_read(&mm->mm_realusers) > 1)
- return (0);
- nh = NULL; /* COMPILER BUG -- hope it is optimized out */
- for (i = DEFAULT_ALLOCATION; i > 0; i >>= 1)
- if ((nh = (struct held_files *)
- kmalloc(i * sizeof (struct held_files),
- GFP_KERNEL)))
- break;
- if (!nh)
- return (-ENOMEM);
- memset(nh, 0, i * sizeof (struct held_files));
- task_lock(p);
- p->mosix.held_files = nh;
- p->mosix.held_allocated = i;
- task_unlock(p);
- new = 0;
- } else {
- new = -1;
- for (i = 0; i < p->mosix.held_allocated; i++)
- if ((struct file *) p->mosix.held_files[i].f == fp) {
- if (!denywrite
- || p->mosix.held_files[i].denywrite)
- return (FOUND_OLD);
- if (deny_write_access(fp))
- return (-ETXTBSY);
- p->mosix.held_files[i].denywrite = 1;
- return (ADDED_A_DENY);
- } else if (new == -1 && !p->mosix.held_files[i].f)
- new = i;
- if (new == -1) {
- nh = NULL; /* COMPILER BUG -- hope it is optimized
out */
- for (i = DEFAULT_ALLOCATION; i > 0; i >>= 1)
- if ((nh =
- kmalloc((i +
- p->mosix.held_allocated) *
- sizeof (struct held_files),
- GFP_KERNEL)))
- break;
- if (!i)
- return (-ENOMEM);
- for (new = p->mosix.held_allocated + i - 1;
- new >= p->mosix.held_allocated; new--)
- nh[new].f = NULL;
- for (new = 0; new < p->mosix.held_allocated; new++)
- nh[new] = p->mosix.held_files[new];
- oh = p->mosix.held_files;
- task_lock(p);
- p->mosix.held_files = nh;
- p->mosix.held_allocated += i;
- task_unlock(p);
- kfree(oh);
- }
- }
- get_file(fp);
- task_lock(p);
- p->mosix.held_files[new].f = fp;
- task_unlock(p);
- if ((p->mosix.held_files[new].denywrite = denywrite)) {
- if (deny_write_access(fp)) {
- task_lock(p);
- p->mosix.held_files[new].f = NULL;
- task_unlock(p);
- return (-ETXTBSY);
- }
- return (ALLOCATED_NEW_AND_DENY);
- } else
- return (ALLOCATED_NEW);
-}
-
-void
-mosix_undo_last_file_registration(struct file *fp, int result)
-{
- unsigned int i;
- struct mosix_task *m = ¤t->mosix;
-
- if (result == FOUND_OLD)
- return;
- for (i = 0; i < m->held_allocated; i++)
- if ((struct file *) m->held_files[i].f == fp) {
- switch (result) {
- case ADDED_A_DENY:
- case ALLOCATED_NEW_AND_DENY:
- if (!m->held_files[i].denywrite)
- printk
- ("%s:
mosix_undo_last_file_registration - no denywrite\n",
- desc_mostask(m));
- else
- allow_write_access(fp);
- if (result == ADDED_A_DENY)
- break;
- case ALLOCATED_NEW:
- fput(fp);
- task_lock(current);
- m->held_files[i].f = NULL;
- task_unlock(current);
- break;
- }
- return;
- }
- printk("%s: mosix_undo_last_file_registration - not found\n",
- desc_mostask(m));
-}
-
-void
-mosix_update_remote_files(void)
-{
- struct task_struct *p = current;
- struct held_files *h = p->mosix.held_files;
- unsigned int i, j;
- int op, np;
- struct file **rf;
- struct file *fp;
-
- if (!(op = p->mosix.held_allocated))
- return;
- if (deputy_request(DEP_LISTHOLD, NULL, 0, NULL, 0, 0,
- (void **) &np, -sizeof (int)))
- deputy_die_on_communication();
- if (np < 0 || (np && comm_recvdata((void **) &rf) < 0))
- deputy_die_on_communication();
- for (j = 0; j < op; j++)
- h[j].denywrite = (h[j].denywrite != 0) | 2;
- for (i = 0; i < np; i++) {
- for (j = 0; j < op; j++)
- if (h[j].f == rf[i]) {
- h[j].denywrite &= ~2;
- break;
- }
- if (j == op)
- panic("mosix_update_remote_files: not listed");
- }
- for (j = 0; j < op; j++)
- if ((fp = h[j].f) && (h[j].denywrite & 2)) {
- task_lock(p);
- h[j].f = NULL;
- task_unlock(p);
- if (h[j].denywrite & 1)
- allow_write_access(fp);
- fput(fp);
- }
- if (np)
- comm_free(rf);
-}
-
-int
-mosix_rebuild_file_list(void)
-{
- struct task_struct *p = current;
- struct vm_area_struct *vma, *vmb;
- struct mm_struct *mm = p->mm;
- struct held_files *hf = NULL, *old;
- unsigned int i, n;
- int oldn;
- unsigned int denywrite;
- struct file *this;
-
- if (p->mosix.dflags & DDEPUTY) {
- if (p->mosix.dflags & DINCOMING)
- p->mosix.dflags |= DDELAYHELD;
- else
- mosix_update_remote_files();
- return (0);
- }
- if (atomic_read(&mm->mm_realusers) > 1) {
- mosix_clear_all_held_files(p); /* discard old */
- return (-EBUSY); /* thread */
- }
- /* because we are the only clone, no MM lock is needed */
- /* and the initial count cannot change */
-
- for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next)
- if ((this = vma->vm_file)) {
- for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next)
- if (vmb->vm_file == vma->vm_file)
- break;
- if (vmb == vma) {
- if (this->f_dentry->d_inode->i_mapping->
- i_mmap_shared) {
- monkey:
- mosix_clear_all_held_files(p);
- tell_process(p, DREQ_CHECKSTAY);
- return (-EDIST);
- }
- n++;
- }
- }
- if (n && !(hf = kmalloc(n * sizeof (struct held_files), GFP_KERNEL))) {
- mosix_clear_all_held_files(p); /* discard old */
- return (-ENOMEM);
- }
- for (n = 0, vma = mm->mmap; vma; vma = vma->vm_next)
- if ((this = vma->vm_file)) {
- for (vmb = mm->mmap; vmb != vma; vmb = vmb->vm_next)
- if (vmb->vm_file == this)
- goto already_placed;
- denywrite = 0;
- for (; vmb; vmb = vmb->vm_next)
- if (vmb->vm_file == this
- && (vmb->vm_flags & VM_DENYWRITE)) {
- denywrite = 1;
- atomic_dec(&this->f_dentry->d_inode->
- i_writecount);
- break;
- }
- get_file(this);
- hf[n].f = this;
- hf[n++].denywrite = denywrite;
- already_placed:;
- }
- /* must not use "mosix_clear_all_held_files" because it could sleep */
- /* in 'fput' when another held file becomes VMONKEY */
- oldn = p->mosix.held_allocated;
- old = p->mosix.held_files;
- task_lock(p);
- p->mosix.held_files = hf;
- p->mosix.held_allocated = n;
- task_unlock(p);
- if (old) {
- for (i = 0; i < oldn; i++)
- if ((this = old[i].f)) {
- if (old[i].denywrite)
- allow_write_access(this);
- fput(this);
- }
- kfree(old);
- }
- /* final race check: has any file been made monkey meanwhile? */
- for (i = 0; i < n; i++)
- if (hf[i].f->f_dentry->d_inode->i_mapping->i_mmap_shared)
- goto monkey;
- return (0);
-}
-
-int
-fork_mosix_remote_files(struct task_struct *p)
-{
- unsigned int i;
- struct file *fp;
-
- if (!(p->mosix.held_allocated = current->mosix.held_allocated))
- return (0);
- if (!(p->mosix.held_files = kmalloc(p->mosix.held_allocated *
- sizeof (struct held_files),
- GFP_KERNEL))) {
- p->mosix.held_allocated = 0;
- return (-ENOMEM);
- }
- for (i = 0; i < current->mosix.held_allocated; i++)
- if ((fp = (struct file *) current->mosix.held_files[i].f)) {
- get_file(fp);
- p->mosix.held_files[i].f = fp;
- if ((p->mosix.held_files[i].denywrite =
- current->mosix.held_files[i].denywrite))
- atomic_dec(&fp->f_dentry->d_inode->
- i_writecount);
- } else
- p->mosix.held_files[i].f = NULL;
- return (0);
-}
-
-void
-mosix_clear_all_held_files(struct task_struct *p)
-{
- unsigned int i;
- int n;
- struct held_files *h;
-
- if (!(n = p->mosix.held_allocated))
- return;
- h = p->mosix.held_files;
- task_lock(p);
- p->mosix.held_files = NULL;
- p->mosix.held_allocated = 0;
- task_unlock(p);
- for (i = 0; i < n; i++)
- if (h[i].f) {
- if (h[i].denywrite)
- allow_write_access(h[i].f);
- fput(h[i].f);
- }
- kfree(h);
-}
-
-int
-task_maps_ip(struct task_struct *p, struct inode *ip)
-{
- unsigned int i;
- int n;
- int ret = 0;
- struct held_files *h;
-
- task_lock(p);
- if ((n = p->mosix.held_allocated))
- for (h = p->mosix.held_files, i = 0; i < n; i++)
- if (h[i].f && (h[i].f)->f_dentry->d_inode == ip) {
- ret = 1;
- break;
- }
- task_unlock(p);
- return (ret);
-}
diff -Naur linux-2.4.26-om1/hpc/service.c linux-2.4.26-om1-o/hpc/service.c
--- linux-2.4.26-om1/hpc/service.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/service.c 2006-05-07 17:56:02.000000000 +0530
@@ -227,6 +227,7 @@
struct vm_area_struct *vma;
int count = 0;
int isfile;
+ int isshared = 0;
unsigned long start, addr, pgd_end, pmd_end, pte_end;
pgd_t *pgdir;
pmd_t *pmdir;
@@ -254,6 +255,7 @@
start = addr;
pgdir = pgd_offset(mm, start);
isfile = (vma->vm_file != NULL);
+ isshared = !(!(vma->vm_flags & VM_SHARED));
for (addr = start; addr < vma->vm_end;
addr = pgd_end, pgdir++) {
if (let_go-- == 0) {
@@ -281,8 +283,8 @@
if (pte_end > pmd_end)
pte_end = pmd_end;
if (pte_present(*pte) ?
- (isfile
- &&
!pte_really_dirty(*pte))
+ (isfile &&
+ (isshared ||
!pte_really_dirty(*pte)))
: pte_none(*pte)) {
if (isfile
&& count_in_file)
diff -Naur linux-2.4.26-om1/hpc/shm_comm.c linux-2.4.26-om1-o/hpc/shm_comm.c
--- linux-2.4.26-om1/hpc/shm_comm.c 1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/shm_comm.c 2006-05-07 17:56:02.000000000 +0530
@@ -0,0 +1,452 @@
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/poll.h>
+#include <linux/hpcctl.h>
+#include <net/sock.h>
+#include <hpc/defs.h>
+#include <hpc/routines.h>
+#include <hpc/protocol.h>
+#include <linux/hpc.h>
+#include <asm/uaccess.h>
+#include <linux/smp_lock.h>
+#include <linux/swap.h>
+#include <linux/pagemap.h>
+#include <linux/stddef.h>
+#include <hpc/comm.h>
+#include <hpc/debug.h>
+#include <hpc/hpcversion.h>
+#include <hpc/balance.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
+
+
+static char MIGSHMDSTR[] = "MigShmD";
+
+
+static struct mosix_addr *fill_to_addr(int mos,struct mosix_addr *to,unsigned
short int port);
+
+
+static int
+info_recv_message(struct shm_request *request);
+
+int
+mosix_migshm_daemon(void *nothing)
+{
+ struct task_struct *p = current;
+ struct shm_request shm_req;
+ static struct mosix_link *link;
+
+ common_daemon_setup(MIGSHMDSTR, 1);
+
+ restart:
+ wait_for_mosix_configuration(NULL);
+
+ if (!p->mosix.contact) {
+ if(!(link = comm_open(COMM_MIGSHM,0,0UL))) +
goto h;
+ comm_use(p, link);
+ if (!p->mosix.contact)
+ {
+ h: printk("%s: failed comm_open - exiting\n",MIGSHMDSTR);
+ if(p->mosix.contact)
+ comm_close(NULL);
+ do_exit(0);
+ }
+ }
+ + while (1) {
+ comm_wait();
+ + /* if openMosix was shut down - restart everything */
+ if (!PE) {
+ comm_close(NULL);
+ comm_free_linkpool();
+ goto restart;
+ }
+ + info_recv_message(&shm_req);
+ }
+ }
+
+static int
+info_recv_message(struct shm_request *request)
+{
+ struct mosix_addr ra; /* reply address */
+ struct mosix_link *l = current->mosix.contact;
+ struct shm_page *shm_page;
+ struct page *page;
+ int n;
+ int sender;
+ unsigned long dummy;
+ while (1) {
+ n = comm_recvfrom(request, sizeof(struct shm_request), l, &ra,
0);
+ if (n == -EDIST )
+ continue; /* message > bufsize */
+
+ if (n < 0)
+ return (0);
+
+ if (n < sizeof (struct shm_request)) {
+ continue;
+ }
+ sender = request->pe;
+ if (sender > MAXPE ||((request->which != INVALIDATE) && (sender
!= net_to_mos(&ra)))) {
+ continue;
+ }
+
+ if (sender == PE) {
+ printk
+ ("WARNING: Another computer is masquerading as same
openMosix node as this (%d)!\n",
+ PE);
+ continue;
+ }
+ if((request->which == GET_FILE) || (request->which ==
PUT_FILE)) {
+ unsigned long dummy = 0;
+ +
+ if(request->which == GET_FILE)
+ get_file((struct file
*)request->rem_shm_page_addr);
+ else + fput((struct file
*)request->rem_shm_page_addr);
+
+ comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+ continue;
+ }
+ + shm_page = request->rem_shm_page_addr;
+ + shm_pagecache_get(shm_page);
+ + switch(request->which) {
+
+ case INVALIDATE:
+
+ if(!(shm_page->state & AT_HOME)) {
+ page =
find_get_page(shm_page->mapping,shm_page->index);
+ + invalidate(shm_page,page,1);
+
+ page_cache_release(page);
+ }
+
+ request->rem_shm_page_addr =
shm_page->next_addr;
+
+ if(request->next == 0) +
request->next = ((struct sockaddr_in *)(&(ra.saddr)))->sin_port;
+
+ if(shm_page->next != request->pe) +
comm_sendto(shm_page->next, request, sizeof (struct shm_request), l,
+
fill_to_addr(shm_page->next,&ra,MIGSHM_DEAMON_PORT));
+ else +
comm_sendto(shm_page->next, &dummy,sizeof(dummy),l,
+
fill_to_addr(shm_page->next,&ra,request->next));
+
+ break;
+
+
+ case FORWARD_REQUEST_READ:
+ case FORWARD_REQUEST_WRITE:
+ + if(request->which & FORWARD_REQUEST_READ) {
+ shm_page->next = request->next;
+ shm_page->next_addr =
request->next_addr; + shm_page->prev =
request->prev;
+ shm_page->prev_addr =
request->prev_addr;
+ } +
+ page =
find_get_page(shm_page->mapping,shm_page->index);
+
+ invalidate(shm_page,page,(request->which &
FORWARD_REQUEST_WRITE)); +
+
comm_sendto(COMM_TOADDR,kmap(page),PAGE_SIZE,l,&ra);
+ kunmap(page);
+ + page_cache_release(page);
+ + break;
+ + case WRITE_BACK:
+ {
+
+ struct mosix_link *mlink=NULL;
+ struct mosix_addr from;
+ + spin_lock(&shm_page->shm_lock); +
+ if(shm_page->state & PERM_ERR) {
+ shm_page->state &=
~(PERM_ERR|STATE_MASK);
+ shm_page->state |= BUSY_EXCLUSIVE;
+ shm_page->readers = shm_page->writers =
0;
+ dummy = 0;
+ spin_unlock(&shm_page->shm_lock);
+ goto l;
+ }
+
+ switch(shm_page->state & STATE_MASK) {
+ + case BUSY_SHARED:
+ case BUSY_EXCLUSIVE:
+
+
spin_unlock(&shm_page->shm_lock);
+ dummy = 1;
+ break;
+
+ case EXCLUSIVE: +
+ if(!shm_page->readers) {
+ shm_page->state &= ~
EXCLUSIVE;
+ shm_page->state |=
BUSY_EXCLUSIVE;
+ dummy = 0;
+ } else
+ dummy = 1;
+
+
spin_unlock(&shm_page->shm_lock);
+ break;
+ }
+ l:
+
+ if(!dummy) {
+ mlink = comm_open(MIGSHM_COMM,
&from,comm_connect_timo);
+ if(!mlink) break;
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),mlink,&ra);
+ } else
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+
+ if(!dummy) {
+
+ page =
find_or_create_page(shm_page->mapping,shm_page->index,GFP_NOFS);
+
+
comm_recvfrom(kmap(page),PAGE_SIZE,mlink,&ra,0);
+ SetPageUptodate(page);
+ set_page_dirty(page);
+ shm_page->owner = PE;
+ unlock_page(page);
+ kunmap(page);
+ spin_lock(&shm_page->shm_lock);
+ shm_page->state &= ~BUSY_EXCLUSIVE;
+ shm_page->state |= EXCLUSIVE;
+ spin_unlock(&shm_page->shm_lock);
+
+ page_cache_release(page);
+ comm_close(mlink);
+ shm_pagecache_release(shm_page);
+ }
+
+ }
+
+ break;
+
+ case DROP_PAGE_START:
+
+ dummy = 1;
+ + spin_lock(&shm_page->shm_lock);
+ + if(shm_page->state & UPGRADE_ERR)
+ dummy = 2;
+ else
+ if(((shm_page->state & STATE_MASK) == SHARED)
&& !(shm_page->state & DROPPING)) {
+ shm_page->state |= DROPPING;
+ dummy = 0;
+ }
+
+ spin_unlock(&shm_page->shm_lock); +
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+ +
+ break;
+
+ case DROP_PAGE_END:
+ + shm_page->state &= ~DROPPING;
+ break;
+
+ case DROP_PREV:
+ + shm_page->prev = request->prev;
+ shm_page->prev_addr = request->prev_addr;
+ +
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+
+ break;
+
+ case DROP_NEXT:
+ + shm_page->next = request->next;
+ shm_page->next_addr = request->next_addr;
+
+
comm_sendto(COMM_TOADDR,&dummy,sizeof(dummy),l,&ra);
+ break;
+ }
+
+ shm_pagecache_release(shm_page);
+ }
+}
+
+struct mosix_addr * fill_to_addr(int mos,struct mosix_addr *to,unsigned short
int port)
+{
+ struct sockaddr_in *sa = (struct sockaddr_in *)(&(to->saddr));
+ if(!mos_to_net(mos,sa)) {
+ return NULL;
+ }
+ sa->sin_port = port;
+ return to;
+}
+
+int shm_send_message(int mos,struct shm_page *shm_page,struct page
*buf_page,int which)
+{
+ struct mosix_addr to,from;
+ struct shm_request request;
+ struct task_struct *p = current;
+ int res = 1 ;
+ struct mosix_link *mlink = NULL;
+
+ if(mos && (!fill_to_addr(mos,&to,MIGSHM_DEAMON_PORT))) +
goto out;
+ + mlink = comm_open(MIGSHM_COMM, &from,comm_connect_timo);
+ if(!mlink)
+ goto out; + res = 0;
+ request.pe = PE;
+ switch(which) {
+
+ case FORWARD_REQUEST_READ:
+ case FORWARD_REQUEST_WRITE:
+ + request.which = which;
+ + if(which == FORWARD_REQUEST_READ) { +
request.next = request.prev = PE;
+ request.next_addr = request.prev_addr =
shm_page;
+
+ if(shm_page->prev != mos) {
+ request.next = shm_page->prev;
+ request.next_addr =
shm_page->prev_addr;
+ }
+ } + + request.rem_shm_page_addr =
shm_page->rem_shm_page_addr;
+ + if((comm_sendto(mos, &request, sizeof (struct
shm_request), mlink,&to) < 0) ||
+ (comm_recvfrom(kmap(buf_page),PAGE_SIZE, mlink
,&from,GTIME_OUT) <= 0)) + res = 1; + +
kunmap(buf_page);
+
+ break;
+
+ case INVALIDATE:
+
+ request.which = INVALIDATE;
+ request.rem_shm_page_addr = shm_page->next_addr;
+ + request.next = 0;
+
+ if((comm_sendto(mos ,&request,sizeof(struct
shm_request), mlink, &to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,INT_TIME_OUT) <= 0))
+ res = 1;
+ break; + + case WRITE_BACK:
+
+ request.which = WRITE_BACK;
+ request.rem_shm_page_addr =
shm_page->rem_shm_page_addr;
+ + if((comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+ res = 1;
+
+ if(!res) {
+ +
if(comm_sendto(mos,kmap(buf_page),PAGE_SIZE,mlink,
+ &from) < 0 )
+ res = 1;
+ kunmap(buf_page);
+ }
+ + break;
+
+ case DROP_PAGE:
+ + request.which = DROP_PAGE_START;
+ request.rem_shm_page_addr =
shm_page->rem_shm_page_addr;
+
+ if((comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to) < 0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+ res = 1;
+
+ if(!res) {
+ + case DROP_NEXTPREV:
if(!fill_to_addr(shm_page->prev,&to,MIGSHM_DEAMON_PORT)) {
+ res = 1;
+ break;
+ }
+ case DROP_NEXT:
+ request.which = DROP_NEXT;
+ request.rem_shm_page_addr =
shm_page->prev_addr;
+ request.next = shm_page->next;
+ request.next_addr = shm_page->next_addr;
+
+
if((comm_sendto(shm_page->prev,&request,sizeof(struct shm_request),mlink,&to) <
0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+ res = 1;
+
+ if(which == DROP_NEXT) +
break;
+
+
if(!fill_to_addr(shm_page->next,&to,MIGSHM_DEAMON_PORT)) {
+ res = 1;
+ break;
+ }
+ + request.which = DROP_PREV;
+ request.rem_shm_page_addr =
shm_page->next_addr;
+ request.prev = shm_page->prev;
+ request.prev_addr = shm_page->prev_addr;
+
+
if((comm_sendto(shm_page->next,&request,sizeof(struct shm_request),mlink,&to) <
0) ||
+
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0))
+ res = 1;
+
+ if(which == DROP_NEXTPREV) +
break;
+ + +
if(!fill_to_addr(mos,&to,MIGSHM_DEAMON_PORT)) {
+ res = 1; +
break;
+ }
+ + case DROP_PAGE_END:
+
+ request.which = DROP_PAGE_END; +
request.rem_shm_page_addr = shm_page->rem_shm_page_addr;
+ + if(comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to) < 0)
+ res = 1;
+ }
+
+ break; +
+ case GET_FILE:
+ case PUT_FILE:
+
+ request.which = which;
+ request.rem_shm_page_addr = (struct shm_page
*)shm_page;
+ + if((comm_sendto(mos,&request,sizeof(struct
shm_request),mlink,&to)<0) || +
(comm_recvfrom(&res,sizeof(res),mlink,&from,GTIME_OUT) <= 0)) +
res = 1;
+
+ break; + }
+
+ comm_close(mlink);
+out:
+ return res;
+}
+
diff -Naur linux-2.4.26-om1/hpc/shm_filemap.c
linux-2.4.26-om1-o/hpc/shm_filemap.c
--- linux-2.4.26-om1/hpc/shm_filemap.c 1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/shm_filemap.c 2006-05-07 17:56:02.000000000
+0530
@@ -0,0 +1,209 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+#include <linux/locks.h>
+#include <linux/swap.h>
+#include <linux/smp_lock.h>
+#include <linux/blkdev.h>
+#include <linux/file.h>
+#include <linux/swapctl.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include<linux/wait.h>
+#include <linux/iobuf.h>
+ +#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/mman.h>
+#include <asm/atomic.h>
+ +#include <linux/highmem.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
+
+LIST_HEAD(shm_page_unused_list);
+
+
+spinlock_cacheline_t shm_pagecache_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+
+
+unsigned int shm_page_hash_bits;
+
+struct shm_page **shm_page_hash_table;
+
+void shm_pagecache_release(struct shm_page *shm_page)
+{
+ if(atomic_read(&shm_page->count) == 0) + BUG();
+
+ spin_lock(&shm_pagecache_lock); +
+ atomic_dec(&shm_page->count);
+
+ if((atomic_read(&shm_page->count) == 1) && shm_page->mapping) +
remove_shm_page(shm_page);
+
+ if((atomic_read(&shm_page->count) == 0)) +
list_add(&shm_page->list, &shm_page_unused_list);
+
+ spin_unlock(&shm_pagecache_lock);
+}
+
+static void add_page_to_hash_queue(struct shm_page * page, struct shm_page
**p)
+ {
+ struct shm_page *next = *p;
+ + *p = page;
+ page->next_hash = next;
+ page->pprev_hash = p;
+ if (next)
+ next->pprev_hash = &page->next_hash;
+ }
+static inline void __add_to_page_cache(struct shm_page * page,
+ struct address_space *mapping, unsigned long offset,
+ struct shm_page **hash)
+ { + + shm_pagecache_get(page); + page->index = offset;
+ page->mapping = mapping;
+ add_page_to_hash_queue(page, hash);
+ }
+void add_to_shm_page_cache(struct shm_page * page, struct address_space *
mapping, unsigned long offset)
+{
+ spin_lock(&shm_pagecache_lock);
+ __add_to_page_cache(page, mapping, offset, shm_page_hash(mapping,
offset));
+ spin_unlock(&shm_pagecache_lock);
+}
+
+static inline void remove_page_from_hash_queue(struct shm_page * page)
+{
+ struct shm_page *next = page->next_hash;
+ struct shm_page **pprev = page->pprev_hash;
+ + if (next)
+ next->pprev_hash = pprev;
+ *pprev = next;
+ page->pprev_hash = NULL;
+}
+
+void remove_shm_page(struct shm_page * page)
+ {
+ remove_page_from_hash_queue(page);
+ page->mapping = NULL;
+ atomic_dec(&page->count);
+ }
+
+
+static struct shm_page *alloc_shm_page(void)
+{
+ struct shm_page *shm_page = NULL;
+ struct task_struct *p = current;
+ + spin_lock(&shm_pagecache_lock);
+
+ if(!list_empty(&shm_page_unused_list)) {
+ shm_page = list_entry(shm_page_unused_list.prev,struct
shm_page,list);
+ list_del(&shm_page->list);
+ }
+
+ spin_unlock(&shm_pagecache_lock);
+
+ if(!shm_page) + shm_page =
kmem_cache_alloc(shm_page_cachep,SLAB_KERNEL);
+
+ if(!shm_page)
+ return NULL;
+
+ + memset(shm_page,0,sizeof(struct shm_page));
+ atomic_set(&shm_page->count,1);
+ shm_page->owner = PE;
+ shm_page->prev = shm_page->next = PE;
+ shm_page->prev_addr = shm_page->next_addr = shm_page;
+ shm_page->mapping = NULL;
+ shm_page->readers = shm_page->writers = 0;
+ shm_page->shm_lock = SPIN_LOCK_UNLOCKED;
+ INIT_LIST_HEAD(&shm_page->list);
+ return shm_page;
+}
+
+static inline struct shm_page * __find_page_nolock(struct address_space
*mapping, unsigned long offset, +
struct shm_page *page)
+ {
+ goto inside;
+ + for (;;) {
+ page = page->next_hash;
+ inside:
+ if (!page)
+ goto not_found;
+ if (page->mapping != mapping)
+ continue;
+ if (page->index == offset)
+ break;
+ }
+ + not_found:
+ return page;
+ }
+ + /*
+ * a rather lightweight function, finding and getting a reference to a
+ * hashed page atomically.
+ */
+ struct shm_page * find_get_shm_page(struct address_space *mapping,
+ unsigned long offset, struct shm_page **hash)
+ {
+ struct shm_page *page;
+ + /*
+ * We scan the hash list read-only. Addition to and removal from
+ * the hash-list needs a held write-lock.
+ */
+ spin_lock(&shm_pagecache_lock);
+ page = __find_page_nolock(mapping, offset, *hash);
+ if (page)
+ atomic_inc(&page->count);
+ spin_unlock(&shm_pagecache_lock);
+ return page;
+ }
+ /* + * Same as above, but create the page if required..
+ */
+ struct shm_page * find_or_create_shm_page(struct address_space *mapping,
unsigned long index)
+ {
+ struct shm_page *page;
+ struct shm_page **hash = shm_page_hash(mapping, index);
+ extern struct super_block bad_super_block;
+ + page = find_get_shm_page(mapping, index, hash);
+ + if (!page) {
+ struct shm_page *newpage = alloc_shm_page();
+ if (newpage) {
+ spin_lock(&shm_pagecache_lock);
+ page = __find_page_nolock(mapping, index, *hash);
+ if (likely(!page)) {
+ if((unsigned long)(mapping->host->i_sb) ==
(unsigned long)(&bad_super_block))
+ newpage->state |= IDLE;
+ else {
+ newpage->state |= EXCLUSIVE;
+ newpage->state |= AT_HOME;
+ }
+
+ page = newpage;
+ __add_to_page_cache(page, mapping,
index, hash);
+ newpage = NULL;
+ } else
+ shm_pagecache_get(page);
+ spin_unlock(&shm_pagecache_lock);
+ if (newpage)
+ shm_pagecache_release(newpage);
+ }
+ } + return page;
+ }
+
diff -Naur linux-2.4.26-om1/hpc/syscalls.c linux-2.4.26-om1-o/hpc/syscalls.c
--- linux-2.4.26-om1/hpc/syscalls.c 2006-05-08 15:02:17.000000000 +0530
+++ linux-2.4.26-om1-o/hpc/syscalls.c 2006-05-07 17:56:02.000000000 +0530
@@ -1733,6 +1733,10 @@
break;
}
break;
+ case SHMGET:
+ case SHMAT:
+ case SHMDT:
+ case SEMGET:
case MSGGET: /* added this so we can return -EINVAL in the
default */
break;
case MSGCTL:
diff -Naur linux-2.4.26-om1/include/asm-i386/pgtable.h
linux-2.4.26-om1-o/include/asm-i386/pgtable.h
--- linux-2.4.26-om1/include/asm-i386/pgtable.h 2006-05-08 15:02:19.000000000
+0530
+++ linux-2.4.26-om1-o/include/asm-i386/pgtable.h 2006-05-08
10:49:51.000000000 +0530
@@ -201,7 +201,7 @@
#define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
-#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER |
_PAGE_ACCESSED)
+#define PAGE_SHARED __pgprot(_PAGE_PRESENT |_PAGE_RW | _PAGE_USER |
_PAGE_ACCESSED)
#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
diff -Naur linux-2.4.26-om1/include/hpc/comm.h
linux-2.4.26-om1-o/include/hpc/comm.h
--- linux-2.4.26-om1/include/hpc/comm.h 2006-05-08 15:02:24.000000000 +0530
+++ linux-2.4.26-om1-o/include/hpc/comm.h 2006-05-07 17:56:02.000000000
+0530
@@ -19,6 +19,9 @@
#ifdef __KERNEL__
+#define MIGSHM_DEAMON_PORT 0x3419
+
+
struct mosix_link; /* defined in hpc/comm.c */
struct mosix_addr; /* defined in include/hpc/protocol.h */
struct mosix_task;
@@ -35,7 +38,11 @@
#define COMM_ACCEPT (70002)
#define COMM_MIGD (70003)
#define COMM_INFO (70004)
+#define COMM_MIGSHM (70006)
#define COMM_LOOSE (70005)
+#define MIGSHM_COMM (70007)
+
+
/*
* message flags:
@@ -77,6 +84,9 @@
#define COMM_HLEN (sizeof(struct comm_header))
+#define GTIME_OUT 1
+#define INT_TIME_OUT 2
+
/*
* exported data
*/
@@ -89,6 +99,7 @@
* communication module interface
*/
+extern int comm_getname(struct socket *sock, struct sockaddr *saddr);
extern void comm_startup(void);
extern mosix_link *comm_open(int, mosix_addr *, unsigned long);
extern mosix_link *comm_use(struct task_struct *, mosix_link *);
@@ -119,7 +130,7 @@
extern mosix_link *comm_borrow_linkpool(void);
extern void comm_return_linkpool(mosix_link *);
extern void comm_age_linkpool(void);
-extern void rinode_flush_files(int);
+
extern spinlock_t skown_lock;
diff -Naur linux-2.4.26-om1/include/hpc/hpctask.h
linux-2.4.26-om1-o/include/hpc/hpctask.h
--- linux-2.4.26-om1/include/hpc/hpctask.h 2006-05-08 15:02:24.000000000
+0530
+++ linux-2.4.26-om1-o/include/hpc/hpctask.h 2006-05-07 17:56:02.000000000
+0530
@@ -49,12 +49,6 @@
volatile long bstate; /* backed-up state while in MOSIX */
rwlock_t state_lock; /* changes of bstate */
kernel_cap_t remote_caps; /* effective capabilities on REMOTE */
- struct held_files
- {
- struct file *f; /* a file in use */
- char denywrite; /* whether holding i_writecount down */
- } *held_files; /* files held by remote VM */
- int held_allocated; /* # of entries in "held_inodes" */
struct mosix_link *contact; /* DEPUTY <==> REMOTE connection */
struct task_struct *ancesstor; /* nearest ancesstor when dependent */
uint32_t deputytime; /* ticks spent on DEPUTY */
@@ -194,7 +188,6 @@
#define DTRACESYS2 0x00004000 /* syscall done before 2nd
PT_TRACESYS*/
#define DMUSTBEBACK 0x00008000 /* MUST arrive back home */
#define DDUMPABLE 0x00010000 /* copy of dumpable when DEPUTY
*/
-#define DDELAYHELD 0x00020000 /* rebuild held_files later */
#define DTDUMPABLE 0x00040000 /* copy of task_dumpable when DEPUTY
*/
#define DMIGFILTER 0x00040000 /* process migration is conditioned */
#ifdef CONFIG_MOSIX_DFSA
@@ -214,7 +207,6 @@
#define DREQ_URGENT 0x00000020 /* something urgent
(R=>D) */
#define DREQ_CAPCNG 0x00000040 /* capabilities changed
*/
#define DREQ_INFOCNG 0x00000080 /* disclosed info
changed */
-#define DREQ_FILEUNMAP 0x00000100 /* file(s) were
unmapped */
#ifdef CONFIG_MOSIX_DFSA
#define DREQ_NOTUPTODATE 0x10000000 /* send it all again */
#define DREQ_DFSASYNC 0x20000000 /* DFSA world changed
*/
@@ -232,7 +224,6 @@
* reasons to stay:
*/
-#define DSTAY_FOR_MONKEY 0x00000001 /* using monkey vnode */
#define DSTAY_FOR_DEV 0x00000002 /* mapping a device */
#define DSTAY_FOR_86 0x00000004 /* running in 86 mode */
#define DSTAY_SYSTEM 0x00000008 /* system process (init, oM daemon) */
@@ -249,7 +240,7 @@
#define DNOMIGRATE 0x80000000 /* user requested no auto-migrations */
#define DSTAY (~DNOMIGRATE)
-#define DSTAY_PER_MM
(DSTAY_FOR_MONKEY|DSTAY_FOR_DEV|DSTAY_FOR_MLOCK|DSTAY_FOR_KIOBUF)
+#define DSTAY_PER_MM
(DSTAY_FOR_DEV|DSTAY_FOR_MLOCK|DSTAY_FOR_KIOBUF)
/*
* where to go (whereto)
diff -Naur linux-2.4.26-om1/include/hpc/mig_shm.h
linux-2.4.26-om1-o/include/hpc/mig_shm.h
--- linux-2.4.26-om1/include/hpc/mig_shm.h 1970-01-01 05:30:00.000000000
+0530
+++ linux-2.4.26-om1-o/include/hpc/mig_shm.h 2006-05-07 17:56:02.000000000
+0530
@@ -0,0 +1,73 @@
+#ifndef _MIG_SHM_H
+#define _MIG_SHM_H
+struct shm_pgentry;
+struct shm_page {
+ struct list_head list; + struct address_space *mapping;
+ unsigned long index;
+ struct shm_page *next_hash; + atomic_t count;
+ int prev,next; + unsigned long state; + struct shm_page
**pprev_hash; + unsigned int owner;
+ unsigned int readers;
+ unsigned int writers;
+ struct shm_page *rem_shm_page_addr,*prev_addr,*next_addr;
+ spinlock_t shm_lock;
+};
+
+/*
+struct shm_request {
+ unsigned long which;
+ int pe; + struct shm_page *rem_shm_page_addr;
+ struct shm_page *next_addr,*prev_addr;
+ unsigned long prev,next;
+ struct mosix_addr from;
+};
+struct wb_reply {
+ unsigned long dummy;
+ struct mosix_addr from;
+};
+*/
+
+#define IDLE 0x00000001
+#define SHARED 0x00000002
+#define EXCLUSIVE 0x00000004
+#define BUSY_SHARED 0x00000008
+#define BUSY_EXCLUSIVE 0x00000010
+
+#define DROPPING 0x00000020
+
+#define WITH_WRITE_ACC 0x00000040
+#define WITH_READ_ACC 0x00000080
+#define AT_HOME 0x00000200
+
+#define INVALIDATE 0x00000001
+#define WRITE_BACK 0x00000002
+#define DROP_PAGE 0x00000004
+#define DROP_PAGE_START 0x00000008
+#define DROP_PAGE_END 0x00000010
+#define DROP_PREV 0x00000020
+#define DROP_NEXT 0x00000040
+#define DROP_NEXTPREV 0x00000080
+#define FORWARD_REQUEST_WRITE 0x00000200
+#define FORWARD_REQUEST_READ 0x00000400
+#define GET_FILE 0x00000800
+#define PUT_FILE 0x00001000
+#define UPGRADE_ERR 0x00002000
+#define PERM_ERR 0x00004000
+
+#define ACC_MASK (WITH_WRITE_ACC|WITH_READ_ACC)
+#define STATE_MASK
(IDLE|SHARED|EXCLUSIVE|BUSY_SHARED|BUSY_EXCLUSIVE)
+
+extern void invalidate(struct shm_page *shm_page,struct page *page,int
write_access);
+extern struct page *get_nopage(struct vm_area_struct *vma, unsigned long
address,struct shm_page **shm_page,int write_access);
+extern void wait_here(void);
+
+
+#endif
+
+
+ diff -Naur linux-2.4.26-om1/include/hpc/protocol.h
linux-2.4.26-om1-o/include/hpc/protocol.h
--- linux-2.4.26-om1/include/hpc/protocol.h 2006-05-08 15:02:24.000000000
+0530
+++ linux-2.4.26-om1-o/include/hpc/protocol.h 2006-05-07 17:56:02.000000000
+0530
@@ -59,6 +59,7 @@
int fixed;
unsigned long len;
unsigned long flags;
+ unsigned long prot;
unsigned long pgoff;
int origin;
struct file *fp;
@@ -175,13 +176,48 @@
struct file *fp;
unsigned long offset;
nopage_t nopage;
+ int access;
+ struct shm_page *rem_shm_page_addr;
+};
+struct write_page_h
+{
+ struct dentry *dentry;
+ unsigned long offset;
+};
+struct to_be_unlocked_h
+{
+ struct shm_page *shm_page;
+ struct page *page;
};
-struct page_ret_h
+/*struct page_ret_h
{
int ret;
unsigned long deputytime;
};
+*/
+struct upgrade_h +{
+ struct shm_page *shm_page,*rem_shm_page_addr;
+};
+
+struct shm_request {
+ unsigned long which;
+ int pe;
+ struct shm_page *rem_shm_page_addr;
+ struct shm_page *next_addr,*prev_addr;
+ unsigned long prev,next;
+};
+
+struct shm_page_ret_h
+{
+ int ret;
+ unsigned long deputytime;
+ struct shm_page *rem_shm_page_addr;
+ struct shm_page *next_addr,*prev_addr;
+ unsigned long prev,next;
+
+};
struct rlimit_h
{
@@ -459,6 +495,8 @@
#define REM_BRING_ME_REGS (ANYTIME|0x04)
#define REM_GETALOAD (ANYTIME|0x05)
#define REM_GETTSC (ANYTIME|0x06)
+#define REM_UPGRADE (ANYTIME|0x07)
+//#define REM_WRITE_BACK_PERM (ANYTIME|0X08)
#define REM_NULLMSG 0x01
#define REM_ASIG 0x02
@@ -492,10 +530,13 @@
extern void deputy_add_rusage(struct rusage *);
extern void deputy_analyse_remote_signals(struct asig_h *);
extern int deputy_bring_page(struct bring_page_h *);
+extern int deputy_upgrade(struct upgrade_h *);
extern int deputy_tsc(void);
extern int deputy_more_strings(struct execve_more_strings_h *);
extern int deputy_bring_me_regs(unsigned long *);
extern void deputy_inform_remote_of_overheads(void);
+extern int deputy_writepage(struct write_page_h *g);
+extern int deputy_unlock_page(struct to_be_unlocked_h *head);
/* routines on the REMOTE side of the protocol: */
@@ -511,7 +552,9 @@
extern int remote_setup_args(struct execve_setup_args_h *);
extern int remote_exec_mmap(void);
extern int remote_urgent(void);
+extern int remote_upgrade(struct shm_page *);
extern int remote_readpage(struct file *, struct page *);
+extern int remote_writepage(struct page *);
extern int remote_dump_thread(void);
extern int remote_init_aout_mm(struct exec *);
extern int remote_elf_setup(struct execve_elf_setup_h *);
@@ -535,7 +578,6 @@
extern int remote_verify_write(struct user_copy_h *);
extern int remote_csum_copy_from_user(struct user_csum_copy_h *);
extern int remote_csum_copy_to_user(struct user_csum_copy_h *);
-extern int remote_report_files(void);
extern int remote_setup_frame(struct setupframe_parameters_h *);
extern int remote_nice(long *);
extern int remote_caps(kernel_cap_t *);
@@ -565,6 +607,12 @@
extern unsigned int which_regs_to_send(void);
extern void regs_were_sent(void);
+
+
+extern int mosix_migshm_daemon(void *nothing);
+extern int shm_send_message(int mos,struct shm_page *shm_page,struct page
*buf_page,int which);
+
+
#endif /*__KERNEL__*/
#endif /* CONFIG_MOSIX */
#endif
diff -Naur linux-2.4.26-om1/include/hpc/routines.h
linux-2.4.26-om1-o/include/hpc/routines.h
--- linux-2.4.26-om1/include/hpc/routines.h 2006-05-08 15:02:24.000000000
+0530
+++ linux-2.4.26-om1-o/include/hpc/routines.h 2006-05-07 17:56:02.000000000
+0530
@@ -122,11 +122,8 @@
extern void deputy_main_loop(void);
extern void undeputy(struct task_struct *);
extern void deputy_async_requests(void);
-extern void mosix_clear_all_held_files(struct task_struct *);
-extern int fork_mosix_remote_files(struct task_struct *);
extern void coordinate(int, int);
extern long call_with_regs(void *, struct pt_regs *, struct pt_regs *);
-extern int task_maps_ip(struct task_struct *, struct inode *);
extern void deputy_communication_failed(void);
extern void deputy_die_on_communication(void) ATTRIB_NORET;
@@ -204,6 +201,9 @@
extern int my_mosix_status(void);
extern void set_my_cpuspeed(void);
+
+extern int mosix_migshm_daemon(void *);
+
/* debugging: */
/* macros: */
diff -Naur linux-2.4.26-om1/include/hpc/shm_pagemap.h
linux-2.4.26-om1-o/include/hpc/shm_pagemap.h
--- linux-2.4.26-om1/include/hpc/shm_pagemap.h 1970-01-01 05:30:00.000000000
+0530
+++ linux-2.4.26-om1-o/include/hpc/shm_pagemap.h 2006-05-07
17:56:02.000000000 +0530
@@ -0,0 +1,39 @@
+#ifndef _SHM_PAGEMAP_H
+#define _SHM_PAGEMAP_H
+extern unsigned int shm_page_hash_bits;
+#define SHM_PAGE_HASH_BITS (shm_page_hash_bits)
+#define SHM_PAGE_HASH_SIZE (1<<SHM_PAGE_HASH_BITS)
+
+extern struct shm_page **shm_page_hash_table;
+
+#define shm_wait_table_bits 6
+#define shm_wait_table_shift BITS_PER_LONG - shm_wait_table_bits;
+
+extern struct list_head shm_page_unused_list; +
+
+extern spinlock_cacheline_t shm_pagecache_lock_cacheline;
+#define shm_pagecache_lock (shm_pagecache_lock_cacheline.lock)
+ +static inline unsigned long _shm_page_hashfn(struct address_space * mapping,
unsigned long index)
+{
+#define i (((unsigned long) mapping)/(sizeof(struct inode) & ~ (sizeof(struct
inode) - 1)))
+#define s(x) ((x)+((x)>>SHM_PAGE_HASH_BITS))
+ return s(i+index) & (SHM_PAGE_HASH_SIZE-1);
+#undef i
+#undef s
+}
+ +#define shm_page_hash(mapping,index) (shm_page_hash_table +
_shm_page_hashfn(mapping,index))
+ +
+#define shm_pagecache_get(shm_page) (atomic_inc(&shm_page->count))
+
+extern void shm_pagecache_release(struct shm_page *shm_page);
+extern struct shm_page * find_or_create_shm_page(struct address_space
*mapping, unsigned long index);
+extern void add_to_shm_page_cache(struct shm_page * page, struct address_space
* mapping, unsigned long offset);
+extern void remove_shm_page(struct shm_page * page);
+extern struct shm_page * find_get_shm_page(struct address_space *mapping,
+ unsigned long offset, struct shm_page **hash);
+
+#endif
diff -Naur linux-2.4.26-om1/include/linux/hpc.h
linux-2.4.26-om1-o/include/linux/hpc.h
--- linux-2.4.26-om1/include/linux/hpc.h 2006-05-08 15:02:28.000000000
+0530
+++ linux-2.4.26-om1-o/include/linux/hpc.h 2006-05-08 10:49:51.000000000
+0530
@@ -22,10 +22,6 @@
/* operations on DEPUTY's data-base of REMOTE files: */
-extern int mosix_register_a_file(struct file *, int);
-extern void mosix_undo_last_file_registration(struct file *, int);
-extern int mosix_rebuild_file_list(void);
-extern void mosix_update_remote_files(void);
struct vmalist
{
@@ -60,8 +56,6 @@
extern void mosix_exit(void);
extern void mosix_very_exit(void);
extern void mosix_obtain_registers(unsigned long);
-extern void mosix_bring_monkey_users_back(struct inode *);
-extern void mosix_no_longer_monkey(struct inode *);
extern void mosix_check_for_freedom_to_move(void);
extern int mosix_pre_clone(void);
extern void mosix_post_clone(void);
@@ -126,7 +120,6 @@
*/
#define FATAL_SIGSEGV SIGINT
-#define REMOTE_FILE_RELEASED SIGQUIT
/* other signals that can occur on REMOTE:
* SIGKILL, SIGSEGV, SIGPROF, SIGVTALRM, SIGFPE, SIGBUS, SIGIOT, SIGILL,
diff -Naur linux-2.4.26-om1/include/linux/mm.h
linux-2.4.26-om1-o/include/linux/mm.h
--- linux-2.4.26-om1/include/linux/mm.h 2006-05-08 15:02:27.000000000 +0530
+++ linux-2.4.26-om1-o/include/linux/mm.h 2006-05-08 10:49:51.000000000
+0530
@@ -183,6 +183,7 @@
#ifdef CONFIG_MOSIX
char young;
unsigned long last_young;
+ struct shm_page *shm_page;
#endif /* CONFIG_MOSIX */
} mem_map_t;
@@ -429,6 +430,7 @@
*/
#define NOPAGE_SIGBUS (NULL)
#define NOPAGE_OOM ((struct page *) (-1))
+#define PAGE_BUSY ((struct page *) (-2))
/* The array of struct pages */
extern mem_map_t * mem_map;
diff -Naur linux-2.4.26-om1/include/linux/slab.h
linux-2.4.26-om1-o/include/linux/slab.h
--- linux-2.4.26-om1/include/linux/slab.h 2006-05-08 15:02:27.000000000
+0530
+++ linux-2.4.26-om1-o/include/linux/slab.h 2006-05-08 10:49:51.000000000
+0530
@@ -74,6 +74,9 @@
extern kmem_cache_t *bh_cachep;
extern kmem_cache_t *fs_cachep;
extern kmem_cache_t *sigact_cachep;
+#ifdef CONFIG_MOSIX
+extern kmem_cache_t *shm_page_cachep;
+#endif /* CONFIG_MOSIX */
#endif /* __KERNEL__ */
diff -Naur linux-2.4.26-om1/ipc/shm.c linux-2.4.26-om1-o/ipc/shm.c
--- linux-2.4.26-om1/ipc/shm.c 2006-05-08 15:03:24.000000000 +0530
+++ linux-2.4.26-om1-o/ipc/shm.c 2006-05-07 17:56:02.000000000 +0530
@@ -683,17 +683,17 @@
struct vm_area_struct *shmd, *shmdnext;
int retval = -EINVAL;
-#ifdef CONFIG_MOSIX
- if(current->mosix.dflags & DDEPUTY)
- return(0);
- mosix_rebuild_file_list();
-#endif /* CONFIG_MOSIX */
down_write(&mm->mmap_sem);
for (shmd = mm->mmap; shmd; shmd = shmdnext) {
shmdnext = shmd->vm_next;
if (shmd->vm_ops == &shm_vm_ops
&& shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) ==
(ulong) shmaddr) {
- do_munmap(mm, shmd->vm_start, shmd->vm_end -
shmd->vm_start);
+#ifdef CONFIG_MOSIX
+ if(current->mosix.dflags & DDEPUTY)
+ deputy_munmap(shmd->vm_start,shmd->vm_end -
shmd->vm_start);
+ else +#endif /* CONFIG_MOSIX */
+ do_munmap(mm, shmd->vm_start, shmd->vm_end -
shmd->vm_start);
retval = 0;
}
}
diff -Naur linux-2.4.26-om1/ipc/shm.c.orig linux-2.4.26-om1-o/ipc/shm.c.orig
--- linux-2.4.26-om1/ipc/shm.c.orig 1970-01-01 05:30:00.000000000 +0530
+++ linux-2.4.26-om1-o/ipc/shm.c.orig 2006-05-07 17:47:21.000000000 +0530
@@ -0,0 +1,764 @@
+/*
+ * linux/ipc/shm.c
+ * Copyright (C) 1992, 1993 Krishna Balasubramanian
+ * Many improvements/fixes by Bruno Haible.
+ * Replaced `struct shm_desc' by `struct vm_area_struct', July 1994.
+ * Fixed the shm swap deallocation (shm_unuse()), August 1998 Andrea
Arcangeli.
+ *
+ * /proc/sysvipc/shm support (c) 1999 Dragos Acostachioaie <[email protected]>
+ * BIGMEM support, Andrea Arcangeli <[email protected]>
+ * SMP thread shm, Jean-Luc Boyard <[email protected]>
+ * HIGHMEM support, Ingo Molnar <[email protected]>
+ * Make shmmax, shmall, shmmni sysctl'able, Christoph Rohland <[email protected]>
+ * Shared /dev/zero support, Kanoj Sarcar <kanoj-sJ/[email protected]>
+ * Move the mm functionality over to mm/shmem.c, Christoph Rohland
<[email protected]>
+ * + * Some changes by Moshe Bar to eliminate fh leaking problem in openMosix
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/shm.h>
+#include <linux/init.h>
+#include <linux/file.h>
+#include <linux/mman.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <linux/hpc.h>
+#include "util.h"
+
+struct shmid_kernel /* private to the kernel */
+{ + struct kern_ipc_perm shm_perm;
+ struct file * shm_file;
+ int id;
+ unsigned long shm_nattch;
+ unsigned long shm_segsz;
+ time_t shm_atim;
+ time_t shm_dtim;
+ time_t shm_ctim;
+ pid_t shm_cprid;
+ pid_t shm_lprid;
+};
+
+#define shm_flags shm_perm.mode
+
+static struct file_operations shm_file_operations;
+static struct vm_operations_struct shm_vm_ops;
+
+static struct ipc_ids shm_ids;
+
+#define shm_lock(id) ((struct shmid_kernel*)ipc_lock(&shm_ids,id))
+#define shm_unlock(id) ipc_unlock(&shm_ids,id)
+#define shm_lockall() ipc_lockall(&shm_ids)
+#define shm_unlockall() ipc_unlockall(&shm_ids)
+#define shm_get(id) ((struct shmid_kernel*)ipc_get(&shm_ids,id))
+#define shm_buildid(id, seq) \
+ ipc_buildid(&shm_ids, id, seq)
+
+static int newseg (key_t key, int shmflg, size_t size);
+static void shm_open (struct vm_area_struct *shmd);
+static void shm_close (struct vm_area_struct *shmd);
+#ifdef CONFIG_PROC_FS
+static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int
length, int *eof, void *data);
+#endif
+
+size_t shm_ctlmax = SHMMAX;
+size_t shm_ctlall = SHMALL;
+int shm_ctlmni = SHMMNI;
+
+static int shm_tot; /* total number of shared memory pages */
+
+void __init shm_init (void)
+{
+ ipc_init_ids(&shm_ids, 1);
+#ifdef CONFIG_PROC_FS
+ create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc,
NULL);
+#endif
+}
+
+static inline int shm_checkid(struct shmid_kernel *s, int id)
+{
+ if (ipc_checkid(&shm_ids,&s->shm_perm,id))
+ return -EIDRM;
+ return 0;
+}
+
+static inline struct shmid_kernel *shm_rmid(int id)
+{
+ return (struct shmid_kernel *)ipc_rmid(&shm_ids,id);
+}
+
+static inline int shm_addid(struct shmid_kernel *shp)
+{
+ return ipc_addid(&shm_ids, &shp->shm_perm, shm_ctlmni+1);
+}
+
+
+
+static inline void shm_inc (int id) {
+ struct shmid_kernel *shp;
+
+ if(!(shp = shm_lock(id)))
+ BUG();
+ shp->shm_atim = CURRENT_TIME;
+ shp->shm_lprid = current->pid;
+ shp->shm_nattch++;
+ shm_unlock(id);
+}
+
+/* This is called by fork, once for every shm attach. */
+static void shm_open (struct vm_area_struct *shmd)
+{
+ shm_inc (shmd->vm_file->f_dentry->d_inode->i_ino);
+}
+
+/*
+ * shm_destroy - free the struct shmid_kernel
+ *
+ * @shp: struct to free
+ *
+ * It has to be called with shp and shm_ids.sem locked,
+ * but returns with shp unlocked and freed.
+ */
+static void shm_destroy (struct shmid_kernel *shp)
+{
+ shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ shm_rmid (shp->id);
+ shm_unlock(shp->id);
+ shmem_lock(shp->shm_file, 0);
+ fput (shp->shm_file);
+ kfree (shp);
+}
+
+/*
+ * remove the attach descriptor shmd.
+ * free memory for segment if it is marked destroyed.
+ * The descriptor has already been removed from the current->mm->mmap list
+ * and will later be kfree()d.
+ */
+static void shm_close (struct vm_area_struct *shmd)
+{
+ struct file * file = shmd->vm_file;
+ int id = file->f_dentry->d_inode->i_ino;
+ struct shmid_kernel *shp;
+
+ down (&shm_ids.sem);
+ /* remove from the list of attaches of the shm segment */
+ if(!(shp = shm_lock(id)))
+ BUG();
+ shp->shm_lprid = current->pid;
+ shp->shm_dtim = CURRENT_TIME;
+ shp->shm_nattch--;
+ if(shp->shm_nattch == 0 &&
+ shp->shm_flags & SHM_DEST)
+ shm_destroy (shp);
+ else
+ shm_unlock(id);
+ up (&shm_ids.sem);
+}
+
+static int shm_mmap(struct file * file, struct vm_area_struct * vma)
+{
+ UPDATE_ATIME(file->f_dentry->d_inode);
+ vma->vm_ops = &shm_vm_ops;
+ shm_inc(file->f_dentry->d_inode->i_ino);
+ return 0;
+}
+
+static struct file_operations shm_file_operations = {
+ mmap: shm_mmap
+};
+
+static struct vm_operations_struct shm_vm_ops = {
+ open: shm_open, /* callback for a new vm-area open */
+ close: shm_close, /* callback for when the vm-area is released */
+ nopage: shmem_nopage,
+};
+
+static int newseg (key_t key, int shmflg, size_t size)
+{
+ int error;
+ struct shmid_kernel *shp;
+ int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
+ struct file * file;
+ char name[13];
+ int id;
+
+ if (size < SHMMIN || size > shm_ctlmax)
+ return -EINVAL;
+
+ if (shm_tot + numpages >= shm_ctlall)
+ return -ENOSPC;
+
+ shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_USER);
+ if (!shp)
+ return -ENOMEM;
+ sprintf (name, "SYSV%08x", key);
+ file = shmem_file_setup(name, size);
+ error = PTR_ERR(file);
+ if (IS_ERR(file))
+ goto no_file;
+
+ error = -ENOSPC;
+ id = shm_addid(shp);
+ if(id == -1) + goto no_id;
+ shp->shm_perm.key = key;
+ shp->shm_flags = (shmflg & S_IRWXUGO);
+ shp->shm_cprid = current->pid;
+ shp->shm_lprid = 0;
+ shp->shm_atim = shp->shm_dtim = 0;
+ shp->shm_ctim = CURRENT_TIME;
+ shp->shm_segsz = size;
+ shp->shm_nattch = 0;
+ shp->id = shm_buildid(id,shp->shm_perm.seq);
+ shp->shm_file = file;
+ file->f_dentry->d_inode->i_ino = shp->id;
+ file->f_op = &shm_file_operations;
+ shm_tot += numpages;
+ shm_unlock (id);
+ return shp->id;
+
+no_id:
+ fput(file);
+no_file:
+ kfree(shp);
+ return error;
+}
+
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+{
+ struct shmid_kernel *shp;
+ int err, id = 0;
+
+ down(&shm_ids.sem);
+ if (key == IPC_PRIVATE) {
+ err = newseg(key, shmflg, size);
+ } else if ((id = ipc_findkey(&shm_ids, key)) == -1) {
+ if (!(shmflg & IPC_CREAT))
+ err = -ENOENT;
+ else
+ err = newseg(key, shmflg, size);
+ } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
+ err = -EEXIST;
+ } else {
+ shp = shm_lock(id);
+ if(shp==NULL)
+ BUG();
+ if (shp->shm_segsz < size)
+ err = -EINVAL;
+ else if (ipcperms(&shp->shm_perm, shmflg))
+ err = -EACCES;
+ else
+ err = shm_buildid(id, shp->shm_perm.seq);
+ shm_unlock(id);
+ }
+ up(&shm_ids.sem);
+ return err;
+}
+
+static inline unsigned long copy_shmid_to_user(void *buf, struct shmid64_ds
*in, int version)
+{
+ switch(version) {
+ case IPC_64:
+ return copy_to_user(buf, in, sizeof(*in));
+ case IPC_OLD:
+ {
+ struct shmid_ds out;
+
+ ipc64_perm_to_ipc_perm(&in->shm_perm, &out.shm_perm);
+ out.shm_segsz = in->shm_segsz;
+ out.shm_atime = in->shm_atime;
+ out.shm_dtime = in->shm_dtime;
+ out.shm_ctime = in->shm_ctime;
+ out.shm_cpid = in->shm_cpid;
+ out.shm_lpid = in->shm_lpid;
+ out.shm_nattch = in->shm_nattch;
+
+ return copy_to_user(buf, &out, sizeof(out));
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+struct shm_setbuf {
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+}; +
+static inline unsigned long copy_shmid_from_user(struct shm_setbuf *out, void
*buf, int version)
+{
+ switch(version) {
+ case IPC_64:
+ {
+ struct shmid64_ds tbuf;
+
+ if (copy_from_user(&tbuf, buf, sizeof(tbuf)))
+ return -EFAULT;
+
+ out->uid = tbuf.shm_perm.uid;
+ out->gid = tbuf.shm_perm.gid;
+ out->mode = tbuf.shm_flags;
+
+ return 0;
+ }
+ case IPC_OLD:
+ {
+ struct shmid_ds tbuf_old;
+
+ if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
+ return -EFAULT;
+
+ out->uid = tbuf_old.shm_perm.uid;
+ out->gid = tbuf_old.shm_perm.gid;
+ out->mode = tbuf_old.shm_flags;
+
+ return 0;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static inline unsigned long copy_shminfo_to_user(void *buf, struct shminfo64
*in, int version)
+{
+ switch(version) {
+ case IPC_64:
+ return copy_to_user(buf, in, sizeof(*in));
+ case IPC_OLD:
+ {
+ struct shminfo out;
+
+ if(in->shmmax > INT_MAX)
+ out.shmmax = INT_MAX;
+ else
+ out.shmmax = (int)in->shmmax;
+
+ out.shmmin = in->shmmin;
+ out.shmmni = in->shmmni;
+ out.shmseg = in->shmseg;
+ out.shmall = in->shmall; +
+ return copy_to_user(buf, &out, sizeof(out));
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+static void shm_get_stat (unsigned long *rss, unsigned long *swp) +{
+ struct shmem_inode_info *info;
+ int i;
+
+ *rss = 0;
+ *swp = 0;
+
+ for(i = 0; i <= shm_ids.max_id; i++) {
+ struct shmid_kernel* shp;
+ struct inode * inode;
+
+ shp = shm_get(i);
+ if(shp == NULL)
+ continue;
+ inode = shp->shm_file->f_dentry->d_inode;
+ info = SHMEM_I(inode);
+ spin_lock (&info->lock);
+ *rss += inode->i_mapping->nrpages;
+ *swp += info->swapped;
+ spin_unlock (&info->lock);
+ }
+}
+
+asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds *buf)
+{
+ struct shm_setbuf setbuf;
+ struct shmid_kernel *shp;
+ int err, version;
+
+ if (cmd < 0 || shmid < 0)
+ return -EINVAL;
+
+ version = ipc_parse_version(&cmd);
+
+ switch (cmd) { /* replace with proc interface ? */
+ case IPC_INFO:
+ {
+ struct shminfo64 shminfo;
+
+ memset(&shminfo,0,sizeof(shminfo));
+ shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
+ shminfo.shmmax = shm_ctlmax;
+ shminfo.shmall = shm_ctlall;
+
+ shminfo.shmmin = SHMMIN;
+ if(copy_shminfo_to_user (buf, &shminfo, version))
+ return -EFAULT;
+ /* reading a integer is always atomic */
+ err= shm_ids.max_id;
+ if(err<0)
+ err = 0;
+ return err;
+ }
+ case SHM_INFO:
+ {
+ struct shm_info shm_info;
+
+ memset(&shm_info,0,sizeof(shm_info));
+ down(&shm_ids.sem);
+ shm_lockall();
+ shm_info.used_ids = shm_ids.in_use;
+ shm_get_stat (&shm_info.shm_rss, &shm_info.shm_swp);
+ shm_info.shm_tot = shm_tot;
+ shm_info.swap_attempts = 0;
+ shm_info.swap_successes = 0;
+ err = shm_ids.max_id;
+ shm_unlockall();
+ up(&shm_ids.sem);
+ if(copy_to_user (buf, &shm_info, sizeof(shm_info)))
+ return -EFAULT;
+
+ return err < 0 ? 0 : err;
+ }
+ case SHM_STAT:
+ case IPC_STAT:
+ {
+ struct shmid64_ds tbuf;
+ int result;
+ memset(&tbuf, 0, sizeof(tbuf));
+ shp = shm_lock(shmid);
+ if(shp==NULL)
+ return -EINVAL;
+ if(cmd==SHM_STAT) {
+ err = -EINVAL;
+ if (shmid > shm_ids.max_id)
+ goto out_unlock;
+ result = shm_buildid(shmid, shp->shm_perm.seq);
+ } else {
+ err = shm_checkid(shp,shmid);
+ if(err)
+ goto out_unlock;
+ result = 0;
+ }
+ err=-EACCES;
+ if (ipcperms (&shp->shm_perm, S_IRUGO))
+ goto out_unlock;
+ kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
+ tbuf.shm_segsz = shp->shm_segsz;
+ tbuf.shm_atime = shp->shm_atim;
+ tbuf.shm_dtime = shp->shm_dtim;
+ tbuf.shm_ctime = shp->shm_ctim;
+ tbuf.shm_cpid = shp->shm_cprid;
+ tbuf.shm_lpid = shp->shm_lprid;
+ tbuf.shm_nattch = shp->shm_nattch;
+ shm_unlock(shmid);
+ if(copy_shmid_to_user (buf, &tbuf, version))
+ return -EFAULT;
+ return result;
+ }
+ case SHM_LOCK:
+ case SHM_UNLOCK:
+ {
+/* Allow superuser to lock segment in memory */
+/* Should the pages be faulted in here or leave it to user? */
+/* need to determine interaction with current->swappable */
+ if (!capable(CAP_IPC_LOCK))
+ return -EPERM;
+
+ shp = shm_lock(shmid);
+ if(shp==NULL)
+ return -EINVAL;
+ err = shm_checkid(shp,shmid);
+ if(err)
+ goto out_unlock;
+ if(cmd==SHM_LOCK) {
+ shmem_lock(shp->shm_file, 1);
+ shp->shm_flags |= SHM_LOCKED;
+ } else {
+ shmem_lock(shp->shm_file, 0);
+ shp->shm_flags &= ~SHM_LOCKED;
+ }
+ shm_unlock(shmid);
+ return err;
+ }
+ case IPC_RMID:
+ {
+ /*
+ * We cannot simply remove the file. The SVID states
+ * that the block remains until the last person
+ * detaches from it, then is deleted. A shmat() on
+ * an RMID segment is legal in older Linux and if +
* we change it apps break...
+ *
+ * Instead we set a destroyed flag, and then blow
+ * the name away when the usage hits zero.
+ */
+#ifdef CONFIG_MOSIX
+ /* mosix_rebuild_file_list(); fh leakage fixed - moshe */
+#endif
+ down(&shm_ids.sem);
+ shp = shm_lock(shmid);
+ err = -EINVAL;
+ if (shp == NULL) + goto out_up;
+ err = shm_checkid(shp, shmid);
+ if(err)
+ goto out_unlock_up;
+ if (current->euid != shp->shm_perm.uid &&
+ current->euid != shp->shm_perm.cuid && +
!capable(CAP_SYS_ADMIN)) {
+ err=-EPERM;
+ goto out_unlock_up;
+ }
+ if (shp->shm_nattch){
+ shp->shm_flags |= SHM_DEST;
+ /* Do not find it any more */
+ shp->shm_perm.key = IPC_PRIVATE;
+ shm_unlock(shmid);
+ } else
+ shm_destroy (shp);
+ up(&shm_ids.sem);
+ return err;
+ }
+
+ case IPC_SET:
+ {
+ if(copy_shmid_from_user (&setbuf, buf, version))
+ return -EFAULT;
+ down(&shm_ids.sem);
+ shp = shm_lock(shmid);
+ err=-EINVAL;
+ if(shp==NULL)
+ goto out_up;
+ err = shm_checkid(shp,shmid);
+ if(err)
+ goto out_unlock_up;
+ err=-EPERM;
+ if (current->euid != shp->shm_perm.uid &&
+ current->euid != shp->shm_perm.cuid && +
!capable(CAP_SYS_ADMIN)) {
+ goto out_unlock_up;
+ }
+
+ shp->shm_perm.uid = setbuf.uid;
+ shp->shm_perm.gid = setbuf.gid;
+ shp->shm_flags = (shp->shm_flags & ~S_IRWXUGO)
+ | (setbuf.mode & S_IRWXUGO);
+ shp->shm_ctim = CURRENT_TIME;
+ break;
+ }
+
+ default:
+ return -EINVAL;
+ }
+
+ err = 0;
+out_unlock_up:
+ shm_unlock(shmid);
+out_up:
+ up(&shm_ids.sem);
+ return err;
+out_unlock:
+ shm_unlock(shmid);
+ return err;
+}
+
+/*
+ * Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists.
+ */
+asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
+{
+ struct shmid_kernel *shp;
+ unsigned long addr;
+ unsigned long size;
+ struct file * file;
+ int err;
+ unsigned long flags;
+ unsigned long prot;
+ unsigned long o_flags;
+ int acc_mode;
+ void *user_addr;
+
+ if (shmid < 0)
+ return -EINVAL;
+
+ if ((addr = (ulong)shmaddr)) {
+ if (addr & (SHMLBA-1)) {
+ if (shmflg & SHM_RND)
+ addr &= ~(SHMLBA-1); /* round down */
+ else
+ return -EINVAL;
+ }
+ flags = MAP_SHARED | MAP_FIXED;
+ } else {
+ if ((shmflg & SHM_REMAP))
+ return -EINVAL;
+
+ flags = MAP_SHARED;
+ }
+
+ if (shmflg & SHM_RDONLY) {
+ prot = PROT_READ;
+ o_flags = O_RDONLY;
+ acc_mode = S_IRUGO;
+ } else {
+ prot = PROT_READ | PROT_WRITE;
+ o_flags = O_RDWR;
+ acc_mode = S_IRUGO | S_IWUGO;
+ }
+
+ /*
+ * We cannot rely on the fs check since SYSV IPC does have an
+ * additional creator id...
+ */
+ shp = shm_lock(shmid);
+ if(shp == NULL)
+ return -EINVAL;
+ err = shm_checkid(shp,shmid);
+ if (err) {
+ shm_unlock(shmid);
+ return err;
+ }
+ if (ipcperms(&shp->shm_perm, acc_mode)) {
+ shm_unlock(shmid);
+ return -EACCES;
+ }
+ file = shp->shm_file;
+ size = file->f_dentry->d_inode->i_size;
+ shp->shm_nattch++;
+ shm_unlock(shmid);
+
+#ifdef CONFIG_MOSIX
+ user_addr = (void *) do_mmap_down (file, addr, size, prot, flags, 0);
+#else
+ down_write(¤t->mm->mmap_sem);
+ if (addr && !(shmflg & SHM_REMAP)) {
+ user_addr = ERR_PTR(-EINVAL);
+ if (find_vma_intersection(current->mm, addr, addr + size))
+ goto invalid;
+ /*
+ * If shm segment goes below stack, make sure there is some
+ * space left for the stack to grow (at least 4 pages).
+ */
+ if (addr < current->mm->start_stack &&
+ addr > current->mm->start_stack - size - PAGE_SIZE * 5)
+ goto invalid;
+ }
+ + user_addr = (void*) do_mmap (file, addr, size, prot, flags, 0);
+
+invalid:
+ up_write(¤t->mm->mmap_sem);
+#endif /* CONFIG_MOSIX */
+
+ down (&shm_ids.sem);
+ if(!(shp = shm_lock(shmid)))
+ BUG();
+ shp->shm_nattch--;
+ if(shp->shm_nattch == 0 &&
+ shp->shm_flags & SHM_DEST)
+ shm_destroy (shp);
+ else
+ shm_unlock(shmid);
+ up (&shm_ids.sem);
+
+ *raddr = (unsigned long) user_addr;
+ err = 0;
+ if (IS_ERR(user_addr))
+ err = PTR_ERR(user_addr);
+ return err;
+
+}
+
+/*
+ * detach and kill segment if marked destroyed.
+ * The work is done in shm_close.
+ */
+asmlinkage long sys_shmdt (char *shmaddr)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *shmd, *shmdnext;
+ int retval = -EINVAL;
+
+ down_write(&mm->mmap_sem);
+ for (shmd = mm->mmap; shmd; shmd = shmdnext) {
+ shmdnext = shmd->vm_next;
+ if (shmd->vm_ops == &shm_vm_ops
+ && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) ==
(ulong) shmaddr) {
+#ifdef CONFIG_MOSIX
+ if(current->mosix.dflags & DDEPUTY)
+ deputy_munmap(shmd->vm_start,shmd->vm_end -
shmd->vm_start);
+ else +#endif /* CONFIG_MOSIX */
+ do_munmap(mm, shmd->vm_start, shmd->vm_end -
shmd->vm_start);
+ retval = 0;
+ }
+ }
+ up_write(&mm->mmap_sem);
+ return retval;
+}
+
+#ifdef CONFIG_PROC_FS
+static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int
length, int *eof, void *data)
+{
+ off_t pos = 0;
+ off_t begin = 0;
+ int i, len = 0;
+
+ down(&shm_ids.sem);
+ len += sprintf(buffer, " key shmid perms size cpid
lpid nattch uid gid cuid cgid atime dtime ctime\n");
+
+ for(i = 0; i <= shm_ids.max_id; i++) {
+ struct shmid_kernel* shp;
+
+ shp = shm_lock(i);
+ if(shp!=NULL) {
+#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,
+ shp->shm_perm.key,
+ shm_buildid(i, shp->shm_perm.seq),
+ shp->shm_flags,
+ shp->shm_segsz,
+ shp->shm_cprid,
+ shp->shm_lprid,
+ shp->shm_nattch,
+ shp->shm_perm.uid,
+ shp->shm_perm.gid,
+ shp->shm_perm.cuid,
+ shp->shm_perm.cgid,
+ shp->shm_atim,
+ shp->shm_dtim,
+ shp->shm_ctim);
+ shm_unlock(i);
+
+ pos += len;
+ if(pos < offset) {
+ len = 0;
+ begin = pos;
+ }
+ if(pos > offset + length)
+ goto done;
+ }
+ }
+ *eof = 1;
+done:
+ up(&shm_ids.sem);
+ *start = buffer + (offset - begin);
+ len -= (offset - begin);
+ if(len > length)
+ len = length;
+ if(len < 0)
+ len = 0;
+ return len;
+}
+#endif
diff -Naur linux-2.4.26-om1/kernel/fork.c linux-2.4.26-om1-o/kernel/fork.c
--- linux-2.4.26-om1/kernel/fork.c 2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/kernel/fork.c 2006-05-07 17:56:02.000000000 +0530
@@ -32,6 +32,7 @@
#ifdef CONFIG_MOSIX
#include <linux/hpc.h>
+#include<hpc/mig_shm.h>
#endif /* CONFIG_MOSIX */
/* The idle threads do not count.. */
@@ -1014,6 +1015,11 @@
/* SLAB cache for mm_struct structures (tsk->mm) */
kmem_cache_t *mm_cachep;
+kmem_cache_t *shm_pgentry_cachep;
+
+#ifdef CONFIG_MOSIX
+kmem_cache_t *shm_page_cachep;
+#endif /* CONFIG_MOSIX */
void __init proc_caches_init(void)
{
@@ -1046,4 +1052,15 @@
SLAB_HWCACHE_ALIGN, NULL, NULL);
if(!mm_cachep)
panic("vma_init: Cannot alloc mm_struct SLAB cache");
+
+#ifdef CONFIG_MOSIX +
+ shm_page_cachep = kmem_cache_create("shm_page",
+ sizeof(struct shm_page), 0,
+ SLAB_HWCACHE_ALIGN, NULL, NULL);
+ if(!shm_page_cachep)
+ panic("Cannot alloc shm_page SLAB cache");
+
+#endif /* CONFIG_MOSIX */
+
}
diff -Naur linux-2.4.26-om1/mm/filemap.c linux-2.4.26-om1-o/mm/filemap.c
--- linux-2.4.26-om1/mm/filemap.c 2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/filemap.c 2006-05-07 17:56:02.000000000 +0530
@@ -32,6 +32,8 @@
#ifdef CONFIG_MOSIX
#include <linux/hpc.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
#endif /* CONFIG_MOSIX */
#ifdef CONFIG_MOSIX_DFSA
#include <linux/dfsa_interface.h>
@@ -764,8 +766,8 @@
* This adds the requested page to the page cache if it isn't already there,
* and schedules an I/O to read in its contents from disk.
*/
-static int FASTCALL(page_cache_read(struct file * file, unsigned long
offset));
-static int page_cache_read(struct file * file, unsigned long offset)
+static int FASTCALL(page_cache_read(struct file * file, unsigned long
offset,unsigned long unused));
+static int page_cache_read(struct file * file, unsigned long offset,unsigned
long unused)
{
struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
struct page **hash = page_hash(mapping, offset);
@@ -782,6 +784,12 @@
return -ENOMEM;
if (!add_to_page_cache_unique(page, mapping, offset, hash)) {
+#ifdef CONFIG_MOSIX
+ if(current->mosix.dflags & DREMOTE) {
+ page->shm_page =
find_get_shm_page(mapping,offset,shm_page_hash(mapping,offset));
+ (page->shm_page)->state |= unused;
+ }
+#endif /* CONFIG_MOSIX */
int error = mapping->a_ops->readpage(file, page);
page_cache_release(page);
return error;
@@ -807,7 +815,7 @@
offset = CLUSTER_OFFSET(offset);
while ((pages-- > 0) && (offset < filesize)) {
- int error = page_cache_read(file, offset);
+ int error = page_cache_read(file, offset,0);
if (error < 0)
return error;
offset ++;
@@ -1359,7 +1367,7 @@
if (ra_index >= end_index)
break;
- if (page_cache_read(filp, ra_index) < 0)
+ if (page_cache_read(filp, ra_index,0) < 0)
break;
ahead++;
@@ -1985,7 +1993,7 @@
nr = max;
while (nr) {
- page_cache_read(file, index);
+ page_cache_read(file, index,0);
index++;
nr--;
}
@@ -2081,23 +2089,20 @@
struct inode *inode = mapping->host;
struct page *page, **hash;
unsigned long size, pgoff, endoff;
-
pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) +
area->vm_pgoff;
endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT) +
area->vm_pgoff;
-
+
retry_all:
/*
* An external ptracer can access pages that normally aren't
* accessible..
*/
size = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- if ((pgoff >= size) && (area->vm_mm == current->mm))
+ if ((area->vm_mm == current->mm) && (pgoff >= size))
return NULL;
-
/* The "size" of the file, as far as mmap is concerned, isn't bigger
than the mapping */
if (size > endoff)
size = endoff;
-
/*
* Do we have something in the page cache already?
*/
@@ -2111,22 +2116,29 @@
* Ok, found a page in the page cache, now we need to check
* that it's up-to-date.
*/
- if (!Page_Uptodate(page))
+ +
+ if (!Page_Uptodate(page))
goto page_not_uptodate;
+
success:
/*
* Try read-ahead for sequential areas.
*/
- if (VM_SequentialReadHint(area))
- nopage_sequential_readahead(area, pgoff, size);
-
+ if(!(current->mosix.dflags&DREMOTE)) {
+ if (VM_SequentialReadHint(area))
+ nopage_sequential_readahead(area, pgoff, size);
+ }
/*
* Found the page and have a reference on it, need to check sharing
* and possibly copy it over to another page..
*/
mark_page_accessed(page);
flush_page_to_ram(page);
+
+ +
return page;
no_cached_page:
@@ -2137,17 +2149,17 @@
* Otherwise, we're off the end of a privately mapped file,
* so we need to map a zero page.
*/
- if ((pgoff < size) && !VM_RandomReadHint(area))
+ if ((pgoff < size) &&
!VM_RandomReadHint(area)&&!(current->mosix.dflags&DREMOTE))
error = read_cluster_nonblocking(file, pgoff, size);
else
- error = page_cache_read(file, pgoff);
+ error = page_cache_read(file, pgoff,unused);
/*
* The page we want has now been added to the page cache.
* In the unlikely event that someone removed it in the
* meantime, we'll just come back here and read it again.
*/
- if (error >= 0)
+ if (error >= 0)
goto retry_find;
/*
@@ -2155,11 +2167,19 @@
* system is low on memory, or a problem occurs while trying
* to schedule I/O.
*/
+
+#ifdef CONFIG_MOSIX
+ if(error == -EBUSY) + return PAGE_BUSY; +#endif /*
CONFIG_MOSIX */
+
if (error == -ENOMEM)
return NOPAGE_OOM;
return NULL;
page_not_uptodate:
+ +
lock_page(page);
/* Did it get unhashed while we waited for it? */
@@ -2174,12 +2194,35 @@
UnlockPage(page);
goto success;
}
+#ifdef CONFIG_MOSIX
+ if(current->mosix.dflags & DREMOTE) {
+ page->shm_page =
find_get_shm_page(mapping,pgoff,shm_page_hash(mapping,pgoff));
+ (page->shm_page)->state |= unused;
+ }
+#endif /* CONFIG_MOSIX */
- if (!mapping->a_ops->readpage(file, page)) {
+ if (!(error = mapping->a_ops->readpage(file, page))) {
wait_on_page(page);
if (Page_Uptodate(page))
goto success;
+#ifdef CONFIG_MOSIX
+ else if(current->mosix.dflags & DREMOTE) {
+ page_cache_release(page);
+ return PAGE_BUSY;
+ }
+#endif /* CONFIG_MOSIX */
+ }
+#ifdef CONFIG_MOSIX + else if(current->mosix.dflags & DREMOTE) {
+ page_cache_release(page);
+ if(error == -EBUSY) + return PAGE_BUSY;
+ else if(error == -ENOMEM)
+ return NOPAGE_OOM;
+ else
+ return NULL;
}
+#endif /* CONFIG_MOSIX */
/*
* Umm, take care of errors if the page isn't up-to-date.
@@ -2187,6 +2230,7 @@
* because there really aren't any performance issues here
* and we need to check for errors.
*/
+
lock_page(page);
/* Somebody truncated the page on us? */
@@ -2202,11 +2246,12 @@
goto success;
}
ClearPageError(page);
- if (!mapping->a_ops->readpage(file, page)) {
+ + if (!(mapping->a_ops->readpage(file, page))) {
wait_on_page(page);
if (Page_Uptodate(page))
goto success;
- }
+ }
/*
* Things didn't work out. Return zero to tell the
@@ -2643,7 +2688,7 @@
}
} else {
while ((start < end) && (start < size)) {
- error = page_cache_read(file, start);
+ error = page_cache_read(file, start,0);
start++;
if (error < 0)
break;
@@ -2754,6 +2799,9 @@
int unmapped_error = 0;
int error = -EINVAL;
+ if(current->mosix.dflags & DREMOTE)
+ return 0;
+
down_write(¤t->mm->mmap_sem);
if (start & ~PAGE_MASK)
@@ -3423,10 +3471,32 @@
page_hash_table = (struct page **)
__get_free_pages(GFP_ATOMIC, order);
} while(page_hash_table == NULL && --order > 0);
+ + htable_size = mempages;
+ htable_size *= sizeof(struct shm_page *);
+ for(order = 0; (PAGE_SIZE << order) < htable_size; order++)
+ ;
+
+ do {
+ unsigned long tmp = (PAGE_SIZE << order) / sizeof(struct page
*);
+
+ shm_page_hash_bits = 0;
+ while((tmp >>= 1UL) != 0UL)
+ shm_page_hash_bits++;
+
+ shm_page_hash_table = (struct shm_page **)
+ __get_free_pages(GFP_ATOMIC, order);
+ } while(shm_page_hash_table == NULL && --order > 0);
+
printk("Page-cache hash table entries: %d (order: %ld, %ld bytes)\n",
(1 << page_hash_bits), order, (PAGE_SIZE << order));
if (!page_hash_table)
panic("Failed to allocate page hash table\n");
memset((void *)page_hash_table, 0, PAGE_HASH_SIZE * sizeof(struct page
*));
+
+ if (!shm_page_hash_table)
+ panic("Failed to allocate page hash table\n");
+ memset((void *)shm_page_hash_table, 0, SHM_PAGE_HASH_SIZE *
sizeof(struct shm_page *));
+
}
diff -Naur linux-2.4.26-om1/mm/memory.c linux-2.4.26-om1-o/mm/memory.c
--- linux-2.4.26-om1/mm/memory.c 2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/memory.c 2006-05-07 17:56:02.000000000 +0530
@@ -52,6 +52,8 @@
#ifdef CONFIG_MOSIX
#include <linux/hpc.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
#endif /* CONFIG_MOSIX */
unsigned long max_mapnr;
@@ -991,12 +993,46 @@
static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
unsigned long address, pte_t *page_table, pte_t pte)
{
- struct page *old_page, *new_page;
+ struct page *old_page,*new_page;
+ struct shm_page *shm_page = NULL;
old_page = pte_page(pte);
if (!VALID_PAGE(old_page))
goto bad_wp_page;
+#ifdef CONFIG_MOSIX
+ if(vma->vm_flags & VM_SHARED) {
+
+ spin_unlock(&mm->page_table_lock);
+
+
+ new_page = get_nopage(vma,address,&shm_page,11);
+
+
+ if(shm_page->state & PERM_ERR) {
+ shm_pagecache_release(shm_page);
+ return -1;
+ }
+
+ spin_lock(&shm_page->shm_lock);
+
+ spin_lock(&mm->page_table_lock);
+ if (pte_same(*page_table, pte) && ( shm_page->owner ==0 ||
shm_page->owner == PE) && +
((shm_page->state & STATE_MASK) == EXCLUSIVE) ) +
break_cow(vma,old_page,address,page_table);
+ + spin_unlock(&mm->page_table_lock);
+ spin_unlock(&shm_page->shm_lock);
+ + shm_pagecache_release(shm_page); +
+ if(new_page)
+ page_cache_release(new_page);
+
+ return 1;
+ }
+#endif /* CONFIG_MOSIX */
+
if (!TryLockPage(old_page)) {
int reuse = can_share_swap_page(old_page);
unlock_page(old_page);
@@ -1318,32 +1354,47 @@
{
struct page * new_page;
pte_t entry;
+#ifdef CONFIG_MOSIX
+ struct shm_page *shm_page = NULL;
+ int ret = 2;
+#endif /* CONFIG_MOSIX */
if (!vma->vm_ops || !vma->vm_ops->nopage)
return do_anonymous_page(mm, vma, page_table, write_access,
address);
+
spin_unlock(&mm->page_table_lock);
- new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
+#ifdef CONFIG_MOSIX
+ new_page = get_nopage(vma, address&PAGE_MASK, &shm_page,
+ (!write_access ||
(vma->vm_flags & VM_SHARED)) ? (!(! write_access)) : 2 );
+#else /* CONFIG_MOSIX */
+ new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
+#endif /* CONFIG_MOSIX */
+
if (new_page == NULL) /* no page was available -- SIGBUS */
return 0;
+
if (new_page == NOPAGE_OOM)
return -1;
- /*
- * Should we do an early C-O-W break?
- */
if (write_access && !(vma->vm_flags & VM_SHARED)) {
- struct page * page = alloc_page(GFP_HIGHUSER);
- if (!page) {
- page_cache_release(new_page);
- return -1;
- }
- copy_user_highpage(page, new_page, address);
- page_cache_release(new_page);
- lru_cache_add(page);
- new_page = page;
- }
+ struct page * page = alloc_page(GFP_HIGHUSER);
+ if (!page) {
+ page_cache_release(new_page);
+ return -1;
+ }
+ copy_user_highpage(page, new_page, address);
+ page_cache_release(new_page);
+ lru_cache_add(page);
+ new_page = page;
+ }
+
+
+#ifdef CONFIG_MOSIX
+ if(shm_page) + spin_lock(&(shm_page->shm_lock));
+#endif /* CONFIG_MOSIX */
spin_lock(&mm->page_table_lock);
/*
@@ -1357,26 +1408,59 @@
* handle that later.
*/
/* Only go through if we didn't race with anybody else... */
+
+
+#ifdef CONFIG_MOSIX
+ if (pte_none(*page_table) && + ((!shm_page) ||
(((shm_page->state & STATE_MASK) == EXCLUSIVE && (shm_page->owner == 0 ||
shm_page->owner == PE)) ||
+ (!write_access && (shm_page->state & STATE_MASK) == SHARED)))
) {
+#else
if (pte_none(*page_table)) {
+#endif /* CONFIG_MOSIX */
+
+
if (!PageReserved(new_page))
++mm->rss;
flush_page_to_ram(new_page);
flush_icache_page(vma, new_page);
entry = mk_pte(new_page, vma->vm_page_prot);
- if (write_access)
+ if (write_access)
entry = pte_mkwrite(pte_mkdirty(entry));
+#ifdef CONFIG_MOSIX
+ else
+ entry = pte_wrprotect(entry);
+#endif /* CONFIG_MOSIX */
+
set_pte(page_table, entry);
+#ifdef CONFIG_MOSIX + update_mmu_cache(vma,address,entry);
+#endif /* CONFIG_MOSIX */
} else {
/* One of our sibling threads was faster, back out. */
page_cache_release(new_page);
+#ifdef CONFIG_MOSIX
+ ret = 1;
+#else
spin_unlock(&mm->page_table_lock);
- return 1;
+ return 1;
+#endif /* CONFIG_MOSIX */
+
}
+#ifdef CONFIG_MOSIX
- /* no need to invalidate: a not-present page shouldn't be cached */
+ spin_unlock(&mm->page_table_lock);
+
+ if(shm_page) {
+ spin_unlock(&(shm_page->shm_lock));
+ shm_pagecache_release(shm_page);
+ }
+
+ return ret; /* Major fault */
+#else
update_mmu_cache(vma, address, entry);
- spin_unlock(&mm->page_table_lock);
- return 2; /* Major fault */
+ spin_unlock(&mm->page_table_lock);
+ return 2; /* Major fault */
+#endif /* CONFIG_MOSIX */
}
/*
diff -Naur linux-2.4.26-om1/mm/mmap.c linux-2.4.26-om1-o/mm/mmap.c
--- linux-2.4.26-om1/mm/mmap.c 2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/mmap.c 2006-05-07 17:56:02.000000000 +0530
@@ -27,6 +27,7 @@
#ifdef CONFIG_MOSIX
#include <linux/hpc.h>
+extern struct page *shm_nopage(struct vm_area_struct *vma, unsigned long
address, int unused);
#endif /* CONFIG_MOSIX */
#ifdef CONFIG_MOSIX_DFSA
#include <linux/dfsa_interface.h>
@@ -108,26 +109,11 @@
if (file) {
struct inode *inode = file->f_dentry->d_inode;
-#ifdef CONFIG_MOSIX
- int was_shared = (inode->i_mapping->i_mmap_shared != NULL);
-#endif /* CONFIG_MOSIX */
if (vma->vm_flags & VM_DENYWRITE)
atomic_inc(&inode->i_writecount);
if(vma->vm_next_share)
vma->vm_next_share->vm_pprev_share =
vma->vm_pprev_share;
*vma->vm_pprev_share = vma->vm_next_share;
-#ifdef CONFIG_MOSIX
- if(was_shared && !inode->i_mapping->i_mmap_shared)
- mosix_no_longer_monkey(inode);
- if(current->mosix.dflags & DREMOTE)
- {
- spin_lock_irq(¤t->sigmask_lock);
- current->mosix.asig |= (1 << (REMOTE_FILE_RELEASED-1));
- spin_unlock_irq(¤t->sigmask_lock);
- }
- else
- tell_process(current, DREQ_FILEUNMAP);
-#endif /* CONFIG_MOSIX */
}
#ifdef CONFIG_MOSIX
if(current->mosix.stay & DSTAY_PER_MM)
@@ -190,13 +176,6 @@
if (brk <= mm->brk) {
if (!do_munmap(mm, newbrk, oldbrk-newbrk))
goto set_brk;
-#ifdef CONFIG_MOSIX
- if(process_told(current, DREQ_FILEUNMAP))
- {
- process_ack(current, DREQ_FILEUNMAP);
- mosix_rebuild_file_list();
- }
-#endif /* CONFIG_MOSIX */
goto out;
}
@@ -508,35 +487,29 @@
if (file) {
switch (flags & MAP_TYPE) {
case MAP_SHARED:
- if ((prot & PROT_WRITE) && !(file->f_mode &
FMODE_WRITE))
+ if ((prot & PROT_WRITE) && !(file->f_mode &
FMODE_WRITE))
return -EACCES;
/* Make sure we don't allow writing to an append-only
file.. */
- if (IS_APPEND(file->f_dentry->d_inode) && (file->f_mode
& FMODE_WRITE))
+ if (IS_APPEND(file->f_dentry->d_inode) && (file->f_mode
& FMODE_WRITE))
return -EACCES;
/* make sure there are no mandatory locks on the file.
*/
- if (locks_verify_locked(file->f_dentry->d_inode))
+ if (locks_verify_locked(file->f_dentry->d_inode))
return -EAGAIN;
vm_flags |= VM_SHARED | VM_MAYSHARE;
if (!(file->f_mode & FMODE_WRITE))
vm_flags &= ~(VM_MAYWRITE | VM_SHARED);
-#ifdef CONFIG_MOSIX
- if(file->f_mode & FMODE_WRITE)
- reason_to_come_back |= DSTAY_FOR_MONKEY;
-#endif /* CONFIG_MOSIX */
/* fall through */
case MAP_PRIVATE:
#ifdef CONFIG_MOSIX
- if(file->f_dentry->d_inode->i_mapping->i_mmap_shared)
- reason_to_come_back |= DSTAY_FOR_MONKEY;
if(S_ISCHR(file->f_dentry->d_inode->i_mode))
reason_to_come_back |= DSTAY_FOR_DEV;
if (!(current->mosix.dflags & DINCOMING))
#endif /* CONFIG_MOSIX */
- if (!(file->f_mode & FMODE_READ))
+ if (!(file->f_mode & FMODE_READ))
return -EACCES;
break;
@@ -574,20 +547,14 @@
munmap_back:
vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
if (vma && vma->vm_start < addr + len) {
- if (do_munmap(mm, addr, len))
+ if (do_munmap(mm, addr, len))
return -ENOMEM;
-#ifdef CONFIG_MOSIX
- if(process_told(current, DREQ_FILEUNMAP)) {
- process_ack(current, DREQ_FILEUNMAP);
- mosix_rebuild_file_list();
- }
-#endif /* CONFIG_MOSIX */
goto munmap_back;
}
/* Check against address space limit. */
if ((mm->total_vm << PAGE_SHIFT) + len
- > current->rlim[RLIMIT_AS].rlim_cur)
+ > current->rlim[RLIMIT_AS].rlim_cur)
return -ENOMEM;
/* Private writable mapping? Check memory availability.. */
@@ -627,18 +594,14 @@
vma->vm_raend = 0;
#ifdef CONFIG_MOSIX
- if(file && !(current->mosix.dflags & DREMOTE) && (registration_result =
- mosix_register_a_file(file, (flags & MAP_DENYWRITE) != 0)) < 0)
- {
- error = registration_result;
- goto free_vma;
- }
+ +
/*
* even if we don't end up mapping locally, perform a dummy mapping,
* only to check for fs-specific errors, so we do not fail if and when
* we ever come home:
*/
- if(MMAP_REMOTELY)
+ if(MMAP_REMOTELY && (file || !(flags&MAP_SHARED)))
{
vma->vm_file = file;
if(file && (error = file->f_op->mmap(file, vma)))
@@ -647,10 +610,20 @@
* (perhaps we were mapping /proc/nnnn/mem)? */
if(!MMAP_REMOTELY)
goto again_locally_with_vma;
+
+ if(file)
+ get_file(file);
+
+GO_HERE:
addr = mosix_deputy_mmap(file, addr, (flags & MAP_FIXED) != 0,
len, vma->vm_flags, pgoff,
file ? file->f_dentry->d_inode->i_size : 0,
- file ? vma->vm_ops->nopage : NULL);
+ file ? vma->vm_ops->nopage : NULL); +
+
+ if(file)
+ fput(file);
+
if(IS_ERR((const void *)addr))
{
error = addr;
@@ -663,35 +636,41 @@
/* we did not really want that vma... only to check */
kmem_cache_free(vm_area_cachep, vma);
/* meanwhile someone else could map the same file shared, so:
*/
- if(file && file->f_dentry->d_inode->i_mapping->i_mmap_shared)
+ /*if(file &&
file->f_dentry->d_inode->i_mapping->i_mmap_shared)
{
if(!mosix_go_home(0))
return(-EAGAIN);
- stay_me_and_my_clones(DSTAY_FOR_MONKEY);
- }
+ }*/
return(addr);
}
#endif /* CONFIG_MOSIX */
- if (file) {
+ if(file) {
error = -EINVAL;
- if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
+ if (vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
goto free_vma;
if (vm_flags & VM_DENYWRITE) {
error = deny_write_access(file);
- if (error)
+ if (error)
goto free_vma;
correct_wcount = 1;
}
vma->vm_file = file;
get_file(file);
error = file->f_op->mmap(file, vma);
- if (error)
+ if (error)
goto unmap_and_free_vma;
} else if (flags & MAP_SHARED) {
error = shmem_zero_setup(vma);
if (error)
goto free_vma;
+ file = vma->vm_file;
+ if(MMAP_REMOTELY) {
+ if(vma->vm_flags & (VM_GROWSDOWN|VM_GROWSUP))
+ BUG();
+ vma->vm_flags &=
~(VM_GROWSDOWN|VM_GROWSUP|VM_DENYWRITE);
+ goto GO_HERE;
+ }
}
/* Can addr have changed??
@@ -737,9 +716,9 @@
#ifdef CONFIG_MOSIX
if(reason_to_come_back)
stay_me_and_my_clones(reason_to_come_back);
- if(file && (vm_flags & VM_SHARED))
- mosix_bring_monkey_users_back(file->f_dentry->d_inode);
+
#endif /* CONFIG_MOSIX */
+
return addr;
unmap_and_free_vma:
@@ -752,17 +731,10 @@
zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
free_vma:
kmem_cache_free(vm_area_cachep, vma);
-#ifdef CONFIG_MOSIX
- if(registration_result > 0)
- mosix_undo_last_file_registration(file, registration_result);
-#endif /* CONFIG_MOSIX */
return error;
#ifdef CONFIG_MOSIX
again_locally_with_vma:
kmem_cache_free(vm_area_cachep, vma);
- if(registration_result > 0)
- mosix_undo_last_file_registration(file, registration_result);
- registration_result = 0;
again_locally:
mm = current->mm;
reason_to_come_back = 0;
@@ -1200,13 +1172,6 @@
down_write(&mm->mmap_sem);
ret = do_munmap(mm, addr, len);
up_write(&mm->mmap_sem);
-#ifdef CONFIG_MOSIX
- if(process_told(current, DREQ_FILEUNMAP))
- {
- process_ack(current, DREQ_FILEUNMAP);
- mosix_rebuild_file_list();
- }
-#endif /* CONFIG_MOSIX */
return ret;
}
diff -Naur linux-2.4.26-om1/mm/mremap.c linux-2.4.26-om1-o/mm/mremap.c
--- linux-2.4.26-om1/mm/mremap.c 2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/mremap.c 2006-05-07 17:56:02.000000000 +0530
@@ -375,12 +375,5 @@
down_write(¤t->mm->mmap_sem);
ret = do_mremap(addr, old_len, new_len, flags, new_addr);
up_write(¤t->mm->mmap_sem);
-#ifdef CONFIG_MOSIX
- if(process_told(current, DREQ_FILEUNMAP))
- {
- process_ack(current, DREQ_FILEUNMAP);
- mosix_rebuild_file_list();
- }
-#endif /* CONFIG_MOSIX */
return ret;
}
diff -Naur linux-2.4.26-om1/mm/vmscan.c linux-2.4.26-om1-o/mm/vmscan.c
--- linux-2.4.26-om1/mm/vmscan.c 2006-05-08 15:02:38.000000000 +0530
+++ linux-2.4.26-om1-o/mm/vmscan.c 2006-05-07 17:56:02.000000000 +0530
@@ -25,6 +25,8 @@
#include <linux/file.h>
#include <asm/pgalloc.h>
+#include <hpc/mig_shm.h>
+#include <hpc/shm_pagemap.h>
/*
* "vm_passes" is the number of vm passes before failing the
@@ -680,6 +682,25 @@
zonelist_t *zonelist;
unsigned long pf_free_pages;
int error = 0;
+ struct list_head *entry;
+
+#ifdef CONFIG_MOSIX
+
+again: spin_lock(&shm_pagecache_lock);
+
+ entry = shm_page_unused_list.prev;
+ if(entry != &shm_page_unused_list) {
+ struct shm_page *shm_page;
+ shm_page = list_entry(entry,struct shm_page,list);
+ list_del(&shm_page->list);
+ spin_unlock(&shm_pagecache_lock);
+ kmem_cache_free(shm_page_cachep,shm_page);
+ goto again;
+ }
+
+ spin_unlock(&shm_pagecache_lock);
+
+#endif /* CONFIG_MOSIX */
pf_free_pages = current->flags & PF_FREE_PAGES;
current->flags &= ~PF_FREE_PAGES;
-Ratna Manoj Bolla.
M.Tech 2nd year.
CSE dept. IIT-Guwahati,INDIA.
-------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642