Re: 2.4.26-om1-MigShm

"William Rizzo" <[email protected]>
Newsgroups gmane.linux.cluster.openmosix.devel
Message-ID <[email protected]>
No i didn't.

i'll do asap.

William

2006/5/19, Moshe Bar <moshe-ay74M1d3r6RWk0Htik3J/[email protected]>:
>
> William
>
> Did you get this into your patch?
>
> Moshe
>
> -----Original Message-----
> From: openmosix-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> [mailto:openmosix-devel-admin-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org] On Behalf Of Ratna
> Manoj Bolla
> Sent: Thursday, May 18, 2006 4:00 PM
> To: openmosix-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> Cc: moshe-ay74M1d3r6RWk0Htik3J/[email protected]
> Subject: [Openmosix-devel] 2.4.26-om1-MigShm
>
>
> 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](&current->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_P
> AGE);
> +
> +       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 = &current->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_...
>
> [Messaggio troncato]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.