2.4.26-om1-MigShm
Ratna Manoj Bolla <[email protected]>
| Newsgroups | gmane.linux.cluster.openmosix.devel |
|---|---|
| Message-ID | <[email protected]> |
Below is my latest patch after patching for two more Bugs.
replaced :
-page_table = pte_offset(pmd_offset(pgd_offset(mm,address),address),address);
with:
+pgd_dir = pgd_offset(mm,address);
+if(!pgd_none(*pgd_dir) && !pmd_none(*(pmd_dir =pmd_offset(pgd_dir,address)))) {
+ page_table = pte_offset(pmd_dir,address);
in hpc/shm_comm.c and more...
The following correctness-testing program(producer-consumer) is giving
fine results.
/*
16 different producesr consumer problems wiht thier 16 buffers on a
singls page each having 4 (64/16) producers and 4 consumers totalling 128
processes
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#define SHM_KEY 80
#define SEM_KEY 50
#define NP 16
unsigned char *Buffer[NP];
unsigned long *buf_pos[NP];
unsigned long *out_pos[NP];
int semid[NP];
#define buf_pos (buf_pos[i%NP])
#define out_pos (out_pos[i%NP])
#define semid (semid[i%NP])
#define Buffer (Buffer[i%NP])
unsigned long buf_len = 0XFFF/NP;
struct sembuf v,p;
void producer(int);
void consumer(int);
int main(int argc, char *argv[])
{
int i, x;
unsigned long pno = 64, cno = 64;
int shmid;
key_t key[NP] = {1 ,2, 3, 4,5,6,7,8,9,10,11,12,13,14,15,16};
int flag = SHM_R | SHM_W;
int arg;
char *B;
unsigned long *Buf;
p.sem_op = -1;
v.sem_op = 1;
for(i=0;i<NP;i++) {
semid = semget(SEM_KEY+i,3,0777);
if(semid < 0)
semid = semget(SEM_KEY+i,3,0777|IPC_CREAT);
arg = 1;
semctl(semid,0,SETVAL,arg);
arg = buf_len;
semctl(semid,1,SETVAL,arg);
arg = 0;
semctl(semid,2,SETVAL,arg);
shmid = shmget(SHM_KEY+i, 0xff, flag);
if (shmid < 0)
shmid = shmget(SHM_KEY+i, 0xff, flag | IPC_CREAT);
Buf = (unsigned long *)shmat(shmid, /*addr*/0, /*flag*/0);
buf_pos = Buf;
out_pos = Buf+1;
*buf_pos = *out_pos = 0;
}
for(i = 0; i < pno; i++) {
if(fork()) {
shmid = shmget(10, 0xfff, flag);
if (shmid < 0)
shmid = shmget(10, 0xfff, flag | IPC_CREAT);
B = (char *)shmat(shmid, /*addr*/0, /*flag*/0);
Buffer = B + (i%NP)*buf_len;
producer(i);
goto out;
}
}
for(i = 0; i < cno; i++) {
if(fork()) {
shmid = shmget(10, 0xfff, flag);
if (shmid < 0)
shmid = shmget(10, 0xfff, flag | IPC_CREAT);
B = (char *)shmat(shmid, /*addr*/0, /*flag*/0);
Buffer = B + (i%NP)*buf_len;
consumer(i);
goto out;
}
}
out:
printf("DONE\n");
}
void producer(int i)
{
int times = 50;
while (--times) {
p.sem_num = 1;
semop(semid,&p,1);
p.sem_num = 0;
semop(semid,&p,1);
Buffer[*buf_pos] = times % 26 + 'A';
printf("Producer: %d %c %u\n",i%NP+1,Buffer[*buf_pos],*buf_pos);
(*buf_pos) = ((*buf_pos)+1) % buf_len;
v.sem_num = 0;
semop(semid,&v,1);
v.sem_num = 2;
semop(semid,&v,1);
// sleep(1);
}
}
void consumer(int i)
{
int times = 50;
while (--times) {
p.sem_num = 2;
semop(semid,&p,1);
p.sem_num = 0;
semop(semid,&p,1);
printf("Consumer: %d %c %u\n",i%NP+1,Buffer[*out_pos],*out_pos);
(*out_pos) = ((*out_pos)+1) % buf_len;
v.sem_num = 0;
semop(semid,&v,1);
v.sem_num = 1;
semop(semid,&v,1);
// sleep(1);
}
}
MigShm_Patch.diff :
diff -Naur linux-2.4.26-om1/fs/file_table.c linux-2.4.26-om1-MigShm/fs/file_table.c
--- linux-2.4.26-om1/fs/file_table.c 2006-05-19 01:03:39.000000000 +0530
+++ linux-2.4.26-om1-MigShm/fs/file_table.c 2006-05-17 13:00:21.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-MigShm/fs/read_write.c
--- linux-2.4.26-om1/fs/read_write.c 2006-05-19 01:03:43.000000000 +0530
+++ linux-2.4.26-om1-MigShm/fs/read_write.c 2006-05-17 13:00:21.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-MigShm/hpc/comm.c
--- linux-2.4.26-om1/hpc/comm.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/comm.c 2006-05-17 15:00:11.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 = 10;
/*
* 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 < 5)
+ AVG_TRIES = 5;
}
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-MigShm/hpc/deputy.c
--- linux-2.4.26-om1/hpc/deputy.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/deputy.c 2006-05-17 13:00:21.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-MigShm/hpc/init.c
--- linux-2.4.26-om1/hpc/init.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/init.c 2006-05-17 13:00:21.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-MigShm/hpc/kernel.c
--- linux-2.4.26-om1/hpc/kernel.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/kernel.c 2006-05-17 13:00:21.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-MigShm/hpc/Makefile
--- linux-2.4.26-om1/hpc/Makefile 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/Makefile 2006-05-17 13:00:21.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-MigShm/hpc/mig.c
--- linux-2.4.26-om1/hpc/mig.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/mig.c 2006-05-17 13:00:21.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-MigShm/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-MigShm/hpc/mig_shm.c 2006-05-19 00:35:43.000000000 +0530
@@ -0,0 +1,758 @@
+#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 <asm/tlb.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)
+{
+
+ pgd_t *pgd_dir;
+ pmd_t *pmd_dir;
+ 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;
+
+ ClearPageUptodate(page);
+ ClearPageDirty(page);
+
+ page->shm_page = NULL;
+ shm_pagecache_release(shm_page);
+ }
+ 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);
+
+ pgd_dir = pgd_offset(mm,address);
+ if(!pgd_none(*pgd_dir) && !pmd_none(*(pmd_dir = pmd_offset(pgd_dir,address)))) {
+ page_table = pte_offset(pmd_dir,address);
+
+ if(pte_present(*page_table) && (i || !pte_write(*page_table))) {
+
+ flush_cache_page(vma, address);
+
+ if(!write_access)
+ ptep_set_wrprotect(page_table);
+ else {
+ pte_clear(page_table);
+ mm->rss--;
+ page_cache_release(page);
+ }
+
+ flush_tlb_page(vma, address);
+ }
+ }
+ 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)) {
+ ClearPageUptodate(page);
+ ClearPageDirty(page);
+
+ page->shm_page = NULL;
+ shm_pagecache_release(shm_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) {
+ 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-MigShm/hpc/remote.c
--- linux-2.4.26-om1/hpc/remote.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/remote.c 2006-05-17 23:52:33.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,96 @@
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);
+ ClearPageUptodate(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 +570,66 @@
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 +768,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 +804,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-MigShm/hpc/rinode.c
--- linux-2.4.26-om1/hpc/rinode.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/rinode.c 2006-05-17 13:00:21.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-MigShm/hpc/service.c
--- linux-2.4.26-om1/hpc/service.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/service.c 2006-05-17 13:00:21.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-MigShm/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-MigShm/hpc/shm_comm.c 2006-05-19 00:34:08.000000000 +0530
@@ -0,0 +1,442 @@
+#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 || res)
+ 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 || res)
+ 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;
+ }
+ if(!mlink)
+ BUG();
+ comm_close(mlink);
+out:
+ return res;
+}
+
diff -Naur linux-2.4.26-om1/hpc/shm_filemap.c linux-2.4.26-om1-MigShm/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-MigShm/hpc/shm_filemap.c 2006-05-17 13:00:21.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-MigShm/hpc/syscalls.c
--- linux-2.4.26-om1/hpc/syscalls.c 2006-05-19 01:04:10.000000000 +0530
+++ linux-2.4.26-om1-MigShm/hpc/syscalls.c 2006-05-17 13:00:21.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-MigShm/include/asm-i386/pgtable.h
--- linux-2.4.26-om1/include/asm-i386/pgtable.h 2006-05-19 01:04:13.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/asm-i386/pgtable.h 2006-05-17 13:14:14.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-MigShm/include/hpc/comm.h
--- linux-2.4.26-om1/include/hpc/comm.h 2006-05-19 01:04:16.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/hpc/comm.h 2006-05-17 13:00:21.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-MigShm/include/hpc/hpctask.h
--- linux-2.4.26-om1/include/hpc/hpctask.h 2006-05-19 01:04:16.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/hpc/hpctask.h 2006-05-17 13:00:21.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-MigShm/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-MigShm/include/hpc/mig_shm.h 2006-05-19 01:21:33.000000000 +0530
@@ -0,0 +1,72 @@
+#ifndef _MIG_SHM_H
+#define _MIG_SHM_H
+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-MigShm/include/hpc/protocol.h
--- linux-2.4.26-om1/include/hpc/protocol.h 2006-05-19 01:04:16.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/hpc/protocol.h 2006-05-17 13:00:21.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-MigShm/include/hpc/routines.h
--- linux-2.4.26-om1/include/hpc/routines.h 2006-05-19 01:04:16.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/hpc/routines.h 2006-05-17 13:00:21.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-MigShm/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-MigShm/include/hpc/shm_pagemap.h 2006-05-17 13:00:21.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-MigShm/include/linux/hpc.h
--- linux-2.4.26-om1/include/linux/hpc.h 2006-05-19 01:04:20.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/linux/hpc.h 2006-05-17 13:14:14.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-MigShm/include/linux/mm.h
--- linux-2.4.26-om1/include/linux/mm.h 2006-05-19 01:04:20.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/linux/mm.h 2006-05-17 13:14:14.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-MigShm/include/linux/slab.h
--- linux-2.4.26-om1/include/linux/slab.h 2006-05-19 01:04:19.000000000 +0530
+++ linux-2.4.26-om1-MigShm/include/linux/slab.h 2006-05-17 13:14:14.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-MigShm/ipc/shm.c
--- linux-2.4.26-om1/ipc/shm.c 2006-05-19 01:05:17.000000000 +0530
+++ linux-2.4.26-om1-MigShm/ipc/shm.c 2006-05-17 13:00:21.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/kernel/fork.c linux-2.4.26-om1-MigShm/kernel/fork.c
--- linux-2.4.26-om1/kernel/fork.c 2006-05-19 01:04:30.000000000 +0530
+++ linux-2.4.26-om1-MigShm/kernel/fork.c 2006-05-19 01:22:12.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.. */
@@ -1015,6 +1016,10 @@
/* SLAB cache for mm_struct structures (tsk->mm) */
kmem_cache_t *mm_cachep;
+#ifdef CONFIG_MOSIX
+kmem_cache_t *shm_page_cachep;
+#endif /* CONFIG_MOSIX */
+
void __init proc_caches_init(void)
{
sigact_cachep = kmem_cache_create("signal_act",
@@ -1046,4 +1051,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-MigShm/mm/filemap.c
--- linux-2.4.26-om1/mm/filemap.c 2006-05-19 01:04:30.000000000 +0530
+++ linux-2.4.26-om1-MigShm/mm/filemap.c 2006-05-17 13:00:21.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-MigShm/mm/memory.c
--- linux-2.4.26-om1/mm/memory.c 2006-05-19 01:04:30.000000000 +0530
+++ linux-2.4.26-om1-MigShm/mm/memory.c 2006-05-17 13:00:21.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-MigShm/mm/mmap.c
--- linux-2.4.26-om1/mm/mmap.c 2006-05-19 01:04:31.000000000 +0530
+++ linux-2.4.26-om1-MigShm/mm/mmap.c 2006-05-17 13:00:21.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-MigShm/mm/mremap.c
--- linux-2.4.26-om1/mm/mremap.c 2006-05-19 01:04:31.000000000 +0530
+++ linux-2.4.26-om1-MigShm/mm/mremap.c 2006-05-17 13:00:21.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-MigShm/mm/vmscan.c
--- linux-2.4.26-om1/mm/vmscan.c 2006-05-19 01:04:31.000000000 +0530
+++ linux-2.4.26-om1-MigShm/mm/vmscan.c 2006-05-17 13:00:21.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(IITG-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