Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / kernel_patches / patches / qsnet-rhel4-2.6.patch
1 Index: linux-269-5502/fs/open.c
2 ===================================================================
3 --- linux-269-5502.orig/fs/open.c
4 +++ linux-269-5502/fs/open.c
5 @@ -1029,6 +1029,8 @@ out_error:
6         goto out;
7  }
8  
9 +EXPORT_SYMBOL(sys_open);
10 +
11  #ifndef __alpha__
12  
13  /*
14 Index: linux-269-5502/fs/read_write.c
15 ===================================================================
16 --- linux-269-5502.orig/fs/read_write.c
17 +++ linux-269-5502/fs/read_write.c
18 @@ -145,6 +145,7 @@ asmlinkage off_t sys_lseek(unsigned int 
19  bad:
20         return retval;
21  }
22 +EXPORT_SYMBOL(sys_lseek);
23  
24  #ifdef __ARCH_WANT_SYS_LLSEEK
25  asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
26 Index: linux-269-5502/fs/select.c
27 ===================================================================
28 --- linux-269-5502.orig/fs/select.c
29 +++ linux-269-5502/fs/select.c
30 @@ -539,3 +539,4 @@ out_fds:
31         poll_freewait(&table);
32         return err;
33  }
34 +EXPORT_SYMBOL_GPL(sys_poll);
35 Index: linux-269-5502/fs/exec.c
36 ===================================================================
37 --- linux-269-5502.orig/fs/exec.c
38 +++ linux-269-5502/fs/exec.c
39 @@ -56,6 +56,8 @@
40  #include <linux/kmod.h>
41  #endif
42  
43 +#include <linux/ptrack.h>
44 +
45  int core_uses_pid;
46  char core_pattern[65] = "core";
47  int suid_dumpable = 0;
48 @@ -1214,6 +1216,9 @@ int do_execve(char * filename,
49         if (retval < 0)
50                 goto out;
51  
52 +       /* notify any ptrack callbacks of the process exec */
53 +       ptrack_call_callbacks(PTRACK_PHASE_EXEC, NULL);
54 +
55         retval = search_binary_handler(bprm,regs);
56         if (retval >= 0) {
57                 free_arg_pages(bprm);
58 Index: linux-269-5502/arch/i386/Kconfig
59 ===================================================================
60 --- linux-269-5502.orig/arch/i386/Kconfig
61 +++ linux-269-5502/arch/i386/Kconfig
62 @@ -960,6 +960,9 @@ config REGPARM
63         generate incorrect output with certain kernel constructs when
64         -mregparm=3 is used.
65  
66 +source "mm/Kconfig"
67 +source "kernel/Kconfig"
68 +       
69  endmenu
70  
71  
72 Index: linux-269-5502/arch/i386/defconfig
73 ===================================================================
74 --- linux-269-5502.orig/arch/i386/defconfig
75 +++ linux-269-5502/arch/i386/defconfig
76 @@ -119,6 +119,8 @@ CONFIG_MTRR=y
77  CONFIG_IRQBALANCE=y
78  CONFIG_HAVE_DEC_LOCK=y
79  # CONFIG_REGPARM is not set
80 +CONFIG_IOPROC=y
81 +CONFIG_PTRACK=y
82  
83  #
84  # Power management options (ACPI, APM)
85 Index: linux-269-5502/arch/ia64/Kconfig
86 ===================================================================
87 --- linux-269-5502.orig/arch/ia64/Kconfig
88 +++ linux-269-5502/arch/ia64/Kconfig
89 @@ -316,6 +316,9 @@ config IA64_PALINFO
90           To use this option, you have to ensure that the "/proc file system
91           support" (CONFIG_PROC_FS) is enabled, too.
92  
93 +source "mm/Kconfig"
94 +source "kernel/Kconfig"
95 +
96  source "drivers/firmware/Kconfig"
97  
98  source "fs/Kconfig.binfmt"
99 Index: linux-269-5502/arch/ia64/defconfig
100 ===================================================================
101 --- linux-269-5502.orig/arch/ia64/defconfig
102 +++ linux-269-5502/arch/ia64/defconfig
103 @@ -83,6 +83,8 @@ CONFIG_IA32_SUPPORT=y
104  CONFIG_COMPAT=y
105  CONFIG_PERFMON=y
106  CONFIG_IA64_PALINFO=y
107 +CONFIG_IOPROC=y
108 +CONFIG_PTRACK=y
109  
110  #
111  # Firmware Drivers
112 Index: linux-269-5502/arch/x86_64/Kconfig
113 ===================================================================
114 --- linux-269-5502.orig/arch/x86_64/Kconfig
115 +++ linux-269-5502/arch/x86_64/Kconfig
116 @@ -401,6 +401,9 @@ config X86_MCE_AMD
117            Additional support for AMD specific MCE features such as
118            the DRAM Error Threshold.
119  
120 +source "mm/Kconfig"
121 +source "kernel/Kconfig"
122 +
123  endmenu
124  
125  
126 Index: linux-269-5502/arch/x86_64/defconfig
127 ===================================================================
128 --- linux-269-5502.orig/arch/x86_64/defconfig
129 +++ linux-269-5502/arch/x86_64/defconfig
130 @@ -87,6 +87,8 @@ CONFIG_NR_CPUS=8
131  CONFIG_GART_IOMMU=y
132  CONFIG_SWIOTLB=y
133  CONFIG_X86_MCE=y
134 +CONFIG_IOPROC=y
135 +CONFIG_PTRACK=y
136  
137  #
138  # Power management options
139 Index: linux-269-5502/kernel/ptrack.c
140 ===================================================================
141 --- /dev/null
142 +++ linux-269-5502/kernel/ptrack.c
143 @@ -0,0 +1,145 @@
144 +/*
145 + *    Copyright (C) 2000  Regents of the University of California
146 + *
147 + *    This program is free software; you can redistribute it and/or modify
148 + *    it under the terms of the GNU General Public License as published by
149 + *    the Free Software Foundation; either version 2 of the License, or
150 + *    (at your option) any later version.
151 + *
152 + *    This program is distributed in the hope that it will be useful,
153 + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
154 + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
155 + *    GNU General Public License for more details.
156 + *
157 + *    You should have received a copy of the GNU General Public License
158 + *    along with this program; if not, write to the Free Software
159 + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
160 + *
161 + * Derived from exit_actn.c by
162 + *    Copyright (C) 2003 Quadrics Ltd.
163 + */
164 +
165 +
166 +#include <linux/module.h>
167 +#include <linux/spinlock.h>
168 +#include <linux/sched.h>
169 +#include <linux/ptrack.h>
170 +#include <linux/slab.h>
171 +#include <linux/list.h>
172 +
173 +#include <asm/errno.h>
174 +
175 +int
176 +ptrack_register (ptrack_callback_t callback, void *arg)
177 +{
178 +       struct ptrack_desc *desc = kmalloc (sizeof (struct ptrack_desc), GFP_KERNEL);
179 +       
180 +       if (desc == NULL)
181 +               return -ENOMEM;
182 +
183 +       desc->callback = callback;
184 +       desc->arg      = arg;
185 +       
186 +       list_add_tail (&desc->link, &current->ptrack_list);
187 +       
188 +       return 0;
189 +}
190 +
191 +void
192 +ptrack_deregister (ptrack_callback_t callback, void *arg)
193 +{      
194 +       struct list_head *el, *nel;
195 +       
196 +       list_for_each_safe (el, nel, &current->ptrack_list) {
197 +               struct ptrack_desc *desc = list_entry (el, struct ptrack_desc, link);
198 +               
199 +               if (desc->callback == callback && desc->arg == arg) {
200 +                       list_del (&desc->link);
201 +                       kfree (desc);
202 +               }
203 +       }
204 +}
205 +
206 +int
207 +ptrack_registered (ptrack_callback_t callback, void *arg)
208 +{
209 +       struct list_head *el;
210 +       
211 +       list_for_each (el, &current->ptrack_list) {
212 +               struct ptrack_desc *desc = list_entry (el, struct ptrack_desc, link);
213 +               
214 +               if (desc->callback == callback && desc->arg == arg)
215 +                       return 1;
216 +       }
217 +       return 0;
218 +}      
219 +        
220 +int
221 +ptrack_call_callbacks (int phase, struct task_struct *child)
222 +{
223 +       struct list_head *el, *nel;
224 +       struct ptrack_desc *new;
225 +       int res;
226 +
227 +       if (phase == PTRACK_PHASE_CLONE)
228 +               INIT_LIST_HEAD (&child->ptrack_list);
229 +
230 +       list_for_each_safe (el, nel, &current->ptrack_list) {
231 +               struct ptrack_desc *desc = list_entry (el, struct ptrack_desc, link);
232 +               
233 +              res = desc->callback (desc->arg, phase, child);
234 +               
235 +               switch (phase)
236 +               {
237 +               case PTRACK_PHASE_EXIT:
238 +                       list_del (&desc->link);
239 +                       kfree (desc);
240 +                       break;
241 +                       
242 +               case PTRACK_PHASE_CLONE:
243 +                      switch (res)
244 +                      {
245 +                      case PTRACK_FINISHED:
246 +                              break;
247 +
248 +                      case PTRACK_INNHERIT:
249 +                              if ((new = kmalloc (sizeof (struct ptrack_desc), GFP_ATOMIC)) == NULL)
250 +                              {
251 +                                      /* allocation failed - notify that this process is not going
252 +                                       * to be started by signalling clone failure.
253 +                                       */
254 +                                      desc->callback (desc->arg, PTRACK_PHASE_CLONE_FAIL, child);
255 +                                      
256 +                                      goto failed;
257 +                              }
258 +
259 +                               new->callback = desc->callback;
260 +                               new->arg      = desc->arg;
261 +                               
262 +                               list_add_tail (&new->link, &child->ptrack_list);
263 +                              break;
264 +
265 +                      case PTRACK_DENIED:
266 +                              goto failed;
267 +                       }
268 +                      break;
269 +               }
270 +       }
271 +
272 +       return 0;
273 +
274 + failed:
275 +       while (! list_empty (&child->ptrack_list))
276 +       {
277 +              struct ptrack_desc *desc = list_entry (child->ptrack_list.next, struct ptrack_desc, link);
278 +              
279 +              desc->callback (desc->arg, PTRACK_PHASE_CLONE_FAIL, child);
280 +
281 +              list_del (&desc->link);
282 +              kfree (desc);
283 +       }
284 +       return 1;
285 +}
286 +EXPORT_SYMBOL(ptrack_register);
287 +EXPORT_SYMBOL(ptrack_deregister);
288 +EXPORT_SYMBOL(ptrack_registered);
289 Index: linux-269-5502/kernel/signal.c
290 ===================================================================
291 --- linux-269-5502.orig/kernel/signal.c
292 +++ linux-269-5502/kernel/signal.c
293 @@ -2329,6 +2329,7 @@ sys_kill(int pid, int sig)
294  
295         return kill_something_info(sig, &info, pid);
296  }
297 +EXPORT_SYMBOL_GPL(sys_kill);
298  
299  /**
300   *  sys_tgkill - send signal to one specific thread
301 Index: linux-269-5502/kernel/Kconfig
302 ===================================================================
303 --- /dev/null
304 +++ linux-269-5502/kernel/Kconfig
305 @@ -0,0 +1,14 @@
306 +#
307 +# Kernel subsystem specific config
308 +# 
309 +
310 +# Support for Process Tracking callbacks
311 +#
312 +config PTRACK
313 +       bool "Enable PTRACK process tracking hooks"
314 +       default y
315 +       help
316 +       This option enables hooks to be called when processes are
317 +       created and destoryed in order for a resource management 
318 +       system to know which processes are a member of a "job" and 
319 +       to be able to clean up when the job is terminated.
320 Index: linux-269-5502/kernel/Makefile
321 ===================================================================
322 --- linux-269-5502.orig/kernel/Makefile
323 +++ linux-269-5502/kernel/Makefile
324 @@ -26,6 +26,7 @@ obj-$(CONFIG_AUDIT) += audit.o
325  obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
326  obj-$(CONFIG_AUDITFILESYSTEM) += auditfs.o
327  obj-$(CONFIG_KPROBES) += kprobes.o
328 +obj-$(CONFIG_PTRACK) += ptrack.o
329  
330  ifneq ($(CONFIG_IA64),y)
331  # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
332 Index: linux-269-5502/kernel/exit.c
333 ===================================================================
334 --- linux-269-5502.orig/kernel/exit.c
335 +++ linux-269-5502/kernel/exit.c
336 @@ -32,6 +32,8 @@
337  #include <asm/pgtable.h>
338  #include <asm/mmu_context.h>
339  
340 +#include <linux/ptrack.h>
341 +
342  extern void sem_exit (void);
343  extern struct task_struct *child_reaper;
344  
345 @@ -825,6 +827,9 @@ asmlinkage NORET_TYPE void do_exit(long 
346                 current->tux_exit();
347         }
348  
349 +       /* Notify any ptrack callbacks of the process exit */
350 +       ptrack_call_callbacks(PTRACK_PHASE_EXIT, NULL);
351 +
352         if (unlikely(tsk->audit_context))
353                 audit_free(tsk);
354         __exit_mm(tsk);
355 Index: linux-269-5502/kernel/fork.c
356 ===================================================================
357 --- linux-269-5502.orig/kernel/fork.c
358 +++ linux-269-5502/kernel/fork.c
359 @@ -14,6 +14,7 @@
360  #include <linux/config.h>
361  #include <linux/slab.h>
362  #include <linux/init.h>
363 +#include <linux/ptrack.h>
364  #include <linux/unistd.h>
365  #include <linux/smp_lock.h>
366  #include <linux/module.h>
367 @@ -443,6 +444,9 @@ static struct mm_struct * mm_init(struct
368         mm->page_table_lock = SPIN_LOCK_UNLOCKED;
369         mm->ioctx_list_lock = RW_LOCK_UNLOCKED;
370         mm->ioctx_list = NULL;
371 +#ifdef CONFIG_IOPROC
372 +       mm->ioproc_ops = NULL;
373 +#endif
374         mm->default_kioctx = (struct kioctx)INIT_KIOCTX(mm->default_kioctx, *mm);
375         mm->free_area_cache = TASK_UNMAPPED_BASE;
376  
377 @@ -1312,6 +1316,11 @@ long do_fork(unsigned long clone_flags,
378                         set_tsk_thread_flag(p, TIF_SIGPENDING);
379                 }
380  
381 +               if (ptrack_call_callbacks(PTRACK_PHASE_CLONE, p)) {
382 +                       sigaddset(&p->pending.signal, SIGKILL);
383 +                       set_tsk_thread_flag(p, TIF_SIGPENDING);
384 +               }
385 +
386                 if (!(clone_flags & CLONE_STOPPED))
387                         wake_up_new_task(p, clone_flags);
388                 else
389 Index: linux-269-5502/Makefile
390 ===================================================================
391 --- linux-269-5502.orig/Makefile
392 +++ linux-269-5502/Makefile
393 @@ -1,7 +1,7 @@
394  VERSION = 2
395  PATCHLEVEL = 6
396  SUBLEVEL = 9
397 -EXTRAVERSION = -prep
398 +EXTRAVERSION = -prep.qp3.5.34.4qsnet
399  RHEL_VERSION = 4
400  RHEL_UPDATE = 5
401  NAME=AC 1
402 Index: linux-269-5502/Documentation/vm/ioproc.txt
403 ===================================================================
404 --- /dev/null
405 +++ linux-269-5502/Documentation/vm/ioproc.txt
406 @@ -0,0 +1,467 @@
407 +Linux IOPROC patch overview
408 +===========================
409 +
410 +The network interface for an HPC network differs significantly from
411 +network interfaces for traditional IP networks. HPC networks tend to
412 +be used directly from user processes and perform large RDMA transfers
413 +between theses processes address space. They also have a requirement
414 +for low latency communication, and typically achieve this by OS bypass
415 +techniques.  This then requires a different model to traditional
416 +interconnects, in that a process may need to expose a large amount of
417 +it's address space to the network RDMA.
418 +
419 +Locking down of memory has been a common mechanism for performing
420 +this, together with a pin-down cache implemented in user
421 +libraries. The disadvantage of this method is that large portions of
422 +the physical memory can be locked down for a single process, even if
423 +it's working set changes over the different phases of it's
424 +execution. This leads to inefficient memory utilisation - akin to the
425 +disadvantage of swapping compared to paging.
426 +
427 +This model also has problems where memory is being dynamically
428 +allocated and freed, since the pin down cache is unaware that memory
429 +may have been released by a call to munmap() and so it will still be
430 +locking down the now unused pages.
431 +
432 +Some modern HPC network interfaces implement their own MMU and are
433 +able to handle a translation fault during a network access. The
434 +Quadrics (http://www.quadrics.com) devices (Elan3 and Elan4) have done
435 +this for some time and we expect others to follow the same route in
436 +the relatively near future. These NICs are able to operate in an
437 +environment where paging occurs and do not require memory to be locked
438 +down. The advantage of this is that the user process can expose large
439 +portions of it's address space without having to worry about physical
440 +memory constraints.
441 +
442 +However should the operating system decide to swap a page to disk,
443 +then the NIC must be made aware that it should no longer read/write
444 +from this memory, but should generate a translation fault instead.
445 +
446 +The ioproc patch has been developed to provide a mechanism whereby the
447 +device driver for a NIC can be aware of when a user process's address
448 +translations change, either by paging or by explicitly mapping or
449 +unmapping memory.
450 +
451 +The patch involves inserting callbacks where translations are being
452 +invalidated to notify the NIC that the memory behind those
453 +translations is no longer visible to the application (and so should
454 +not be visible to the NIC). This callback is then responsible for
455 +ensuring that the NIC will not access the physical memory that was
456 +being mapped.
457 +
458 +An ioproc invalidate callback in the kswapd code could be utilised to
459 +prevent memory from being paged out if the NIC is unable to support
460 +network page faulting.
461 +
462 +For NICs which support network page faulting, there is no requirement
463 +for a user level pin down cache, since they are able to page-in their
464 +translations on the first communication using a buffer. However this
465 +is likely to be inefficient, resulting in slow first use of the
466 +buffer. If the communication buffers were continually allocated and
467 +freed using mmap based malloc() calls then this would lead to all
468 +communications being slower than desirable.
469 +
470 +To optimise these warm-up cases the ioproc patch adds calls to
471 +ioproc_update wherever the kernel is creating translations for a user
472 +process. These then allows the device driver to preload translations
473 +so that they are already present for the first network communication
474 +from a buffer.
475 +
476 +Linux 2.6 IOPROC implementation details
477 +=======================================
478 +
479 +The Linux IOPROC patch adds hooks to the Linux VM code whenever page
480 +table entries are being created and/or invalidated. IOPROC device
481 +drivers can register their interest in being informed of such changes
482 +by registering an ioproc_ops structure which is defined as follows;
483 +
484 +extern int ioproc_register_ops(struct mm_struct *mm, struct ioproc_ops *ip);
485 +extern int ioproc_unregister_ops(struct mm_struct *mm, struct ioproc_ops *ip);
486 +
487 +typedef struct ioproc_ops {
488 +       struct ioproc_ops *next;
489 +       void *arg;
490 +
491 +       void (*release)(void *arg, struct mm_struct *mm);
492 +       void (*sync_range)(void *arg, struct vm_area_struct *vma, unsigned long start, unsigned long end);
493 +       void (*invalidate_range)(void *arg, struct vm_area_struct *vma, unsigned long start, unsigned long end);
494 +       void (*update_range)(void *arg, struct vm_area_struct *vma, unsigned long start, unsigned long end);
495 +
496 +       void (*change_protection)(void *arg, struct vm_area_struct *vma, unsigned long start, unsigned long end, pgprot_t newprot);
497 +
498 +       void (*sync_page)(void *arg, struct vm_area_struct *vma, unsigned long address);
499 +       void (*invalidate_page)(void *arg, struct vm_area_struct *vma, unsigned long address);
500 +       void (*update_page)(void *arg, struct vm_area_struct *vma, unsigned long address);
501 +
502 +} ioproc_ops_t;
503 +
504 +ioproc_register_ops
505 +===================
506 +This function should be called by the IOPROC device driver to register
507 +it's interest in PTE changes for the process associated with the passed
508 +in mm_struct.
509 +
510 +The ioproc registration is not inherited across fork() and should be
511 +called once for each process that IOPROC is interested in.
512 +
513 +This function must be called whilst holding the mm->page_table_lock.
514 +
515 +ioproc_unregister_ops
516 +=====================
517 +This function should be called by the IOPROC device driver when it no
518 +longer requires informing of PTE changes in the process associated
519 +with the supplied mm_struct.
520 +
521 +This function is not normally needed to be called as the ioproc_ops
522 +struct is unlinked from the associated mm_struct during the
523 +ioproc_release() call.
524 +
525 +This function must be called whilst holding the mm->page_table_lock.
526 +
527 +ioproc_ops struct
528 +=================
529 +A linked list ioproc_ops structures is hung off the user process
530 +mm_struct (linux/sched.h). At each hook point in the patched kernel,
531 +the ioproc patch will call the associated ioproc_ops callback function
532 +pointer in turn for each registered structure.
533 +
534 +The intention of the callbacks is to allow the IOPROC device driver to
535 +inspect the new or modified PTE entry via the Linux kernel
536 +(e.g. find_pte_map()). These callbacks should not modify the Linux
537 +kernel VM state or PTE entries.
538 +
539 +The ioproc_ops callback function pointers are:
540 +
541 +ioproc_release
542 +==============
543 +The release hook is called when a program exits and all it's vma areas
544 +are torn down and unmapped, i.e. during exit_mmap(). Before each
545 +release hook is called the ioproc_ops structure is unlinked from the
546 +mm_struct.
547 +
548 +No locks are required as the process has the only reference to the mm
549 +at this point.
550 +
551 +ioproc_sync_[range|page]
552 +========================
553 +The sync hooks are called when a memory map is synchronised with its
554 +disk image i.e. when the msync() syscall is invoked. Any future read
555 +or write by the IOPROC device to the associated pages should cause the
556 +page to be marked as referenced or modified.
557 +
558 +Called holding the mm->page_table_lock.
559 +
560 +ioproc_invalidate_[range|page]
561 +==============================
562 +The invalidate hooks are called whenever a valid PTE is unloaded
563 +e.g. when a page is unmapped by the user or paged out by the
564 +kernel. After this call the IOPROC must not access the physical memory
565 +again unless a new translation is loaded.
566 +
567 +Called holding the mm->page_table_lock.
568 +
569 +ioproc_update_[range|page]
570 +==========================
571 +The update hooks are called whenever a valid PTE is loaded
572 +e.g. mmaping memory, moving the brk up, when breaking COW or faulting
573 +in an anonymous page of memory. These give the IOPROC device the
574 +opportunity to load translations speculatively, which can improve
575 +performance by avoiding device translation faults.
576 +
577 +Called holding the mm->page_table_lock.
578 +
579 +ioproc_change_protection
580 +========================
581 +This hook is called when the protection on a region of memory is
582 +changed i.e. when the mprotect() syscall is invoked.
583 +
584 +The IOPROC must not be able to write to a read-only page, so if the
585 +permissions are downgraded then it must honour them. If they are
586 +upgraded it can treat this in the same way as the
587 +ioproc_update_[range|page]() calls.
588 +
589 +Called holding the mm->page_table_lock.
590 +
591 +
592 +Linux 2.6 IOPROC patch details
593 +==============================
594 +
595 +Here are the specific details of each ioproc hook added to the Linux
596 +2.6 VM system and the reasons for doing so:
597 +
598 +++++ FILE
599 +       mm/fremap.c
600 +
601 +==== FUNCTION
602 +       zap_pte
603 +
604 +CALLED FROM
605 +       install_page
606 +       install_file_pte
607 +
608 +PTE MODIFICATION
609 +       ptep_clear_flush
610 +
611 +ADDED HOOKS
612 +       ioproc_invalidate_page
613 +
614 +==== FUNCTION
615 +       install_page
616 +
617 +CALLED FROM
618 +       filemap_populate, shmem_populate
619 +
620 +PTE MODIFICATION
621 +       set_pte
622 +
623 +ADDED HOOKS
624 +       ioproc_update_page
625 +
626 +==== FUNCTION
627 +       install_file_pte
628 +
629 +CALLED FROM
630 +       filemap_populate, shmem_populate
631 +
632 +PTE MODIFICATION
633 +       set_pte
634 +
635 +ADDED HOOKS
636 +       ioproc_update_page
637 +
638 +
639 +++++ FILE
640 +       mm/memory.c
641 +
642 +==== FUNCTION
643 +       zap_page_range
644 +
645 +CALLED FROM
646 +       read_zero_pagealigned, madvise_dontneed, unmap_mapping_range,
647 +       unmap_mapping_range_list, do_mmap_pgoff
648 +
649 +PTE MODIFICATION
650 +       set_pte (unmap_vmas)
651 +
652 +ADDED HOOKS
653 +       ioproc_invalidate_range
654 +
655 +
656 +==== FUNCTION
657 +       zeromap_page_range
658 +
659 +CALLED FROM
660 +       read_zero_pagealigned, mmap_zero
661 +
662 +PTE MODIFICATION
663 +       set_pte (zeromap_pte_range)
664 +
665 +ADDED HOOKS
666 +       ioproc_invalidate_range
667 +       ioproc_update_range
668 +
669 +
670 +==== FUNCTION
671 +       remap_page_range
672 +
673 +CALLED FROM
674 +       many device drivers
675 +
676 +PTE MODIFICATION
677 +       set_pte (remap_pte_range)
678 +
679 +ADDED HOOKS
680 +       ioproc_invalidate_range
681 +       ioproc_update_range
682 +
683 +
684 +==== FUNCTION
685 +       break_cow
686 +
687 +CALLED FROM
688 +       do_wp_page
689 +
690 +PTE MODIFICATION
691 +       ptep_establish
692 +
693 +ADDED HOOKS
694 +       ioproc_invalidate_page
695 +       ioproc_update_page
696 +
697 +
698 +==== FUNCTION
699 +       do_wp_page
700 +
701 +CALLED FROM
702 +       do_swap_page, handle_pte_fault
703 +
704 +PTE MODIFICATION
705 +       ptep_set_access_flags
706 +
707 +ADDED HOOKS
708 +       ioproc_update_page
709 +
710 +
711 +==== FUNCTION
712 +       do_swap_page
713 +
714 +CALLED FROM
715 +       handle_pte_fault
716 +
717 +PTE MODIFICATION
718 +       set_pte
719 +
720 +ADDED HOOKS
721 +       ioproc_update_page
722 +
723 +
724 +==== FUNCTION
725 +       do_anonymous_page
726 +
727 +CALLED FROM
728 +       do_no_page
729 +
730 +PTE MODIFICATION
731 +       set_pte
732 +
733 +ADDED HOOKS
734 +       ioproc_update_page
735 +
736 +
737 +==== FUNCTION
738 +       do_no_page
739 +
740 +CALLED FROM
741 +       do_file_page, handle_pte_fault
742 +
743 +PTE MODIFICATION
744 +       set_pte
745 +
746 +ADDED HOOKS
747 +       ioproc_update_page
748 +
749 +
750 +++++ FILE
751 +       mm/mmap.c
752 +
753 +==== FUNCTION
754 +       unmap_region
755 +
756 +CALLED FROM
757 +       do_munmap
758 +
759 +PTE MODIFICATION
760 +       set_pte (unmap_vmas)
761 +
762 +ADDED HOOKS
763 +       ioproc_invalidate_range
764 +
765 +
766 +==== FUNCTION
767 +       exit_mmap
768 +
769 +CALLED FROM
770 +       mmput
771 +
772 +PTE MODIFICATION
773 +       set_pte (unmap_vmas)
774 +
775 +ADDED HOOKS
776 +       ioproc_release
777 +
778 +
779 +++++ FILE
780 +       mm/mprotect.c
781 +
782 +==== FUNCTION
783 +       change_protection
784 +
785 +CALLED FROM
786 +       mprotect_fixup
787 +
788 +PTE MODIFICATION
789 +       set_pte (change_pte_range)
790 +
791 +ADDED HOOKS
792 +       ioproc_change_protection
793 +
794 +
795 +++++ FILE
796 +       mm/mremap.c
797 +
798 +==== FUNCTION
799 +       move_page_tables
800 +
801 +CALLED FROM
802 +       move_vma
803 +
804 +PTE MODIFICATION
805 +       ptep_clear_flush (move_one_page)
806 +
807 +ADDED HOOKS
808 +       ioproc_invalidate_range
809 +       ioproc_invalidate_range
810 +
811 +
812 +++++ FILE
813 +       mm/rmap.c
814 +
815 +==== FUNCTION
816 +       try_to_unmap_one
817 +
818 +CALLED FROM
819 +       try_to_unmap_anon, try_to_unmap_file
820 +
821 +PTE MODIFICATION
822 +       ptep_clear_flush
823 +
824 +ADDED HOOKS
825 +       ioproc_invalidate_page
826 +
827 +
828 +==== FUNCTION
829 +       try_to_unmap_cluster
830 +
831 +CALLED FROM
832 +       try_to_unmap_file
833 +
834 +PTE MODIFICATION
835 +       ptep_clear_flush
836 +
837 +ADDED HOOKS
838 +       ioproc_invalidate_page
839 +
840 +
841 +
842 +++++ FILE 
843 +       mm/msync.c
844 +
845 +==== FUNCTION
846 +       filemap_sync
847 +
848 +CALLED FROM
849 +       msync_interval
850 +
851 +PTE MODIFICATION
852 +       ptep_clear_flush_dirty (filemap_sync_pte)
853 +
854 +ADDED HOOKS
855 +       ioproc_sync_range
856 +
857 +
858 +++++ FILE
859 +       mm/hugetlb.c
860 +
861 +==== FUNCTION
862 +       zap_hugepage_range
863 +
864 +CALLED FROM
865 +       hugetlb_vmtruncate_list
866 +
867 +PTE MODIFICATION
868 +       ptep_get_and_clear (unmap_hugepage_range)
869 +
870 +ADDED HOOK
871 +       ioproc_invalidate_range
872 +
873 +-- Last update Daniel J Blueman - 24 Mar 2006
874 Index: linux-269-5502/mm/ioproc.c
875 ===================================================================
876 --- /dev/null
877 +++ linux-269-5502/mm/ioproc.c
878 @@ -0,0 +1,52 @@
879 +/*
880 + *    Copyright (C) 2006 Quadrics Ltd
881 + *
882 + *    This program is free software; you can redistribute it and/or modify
883 + *    it under the terms of the GNU General Public License as published by
884 + *    the Free Software Foundation; either version 2 of the License, or
885 + *    (at your option) any later version.
886 + *
887 + *    This program is distributed in the hope that it will be useful,
888 + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
889 + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
890 + *    GNU General Public License for more details.
891 + *
892 + *    You should have received a copy of the GNU General Public License
893 + *    along with this program; if not, write to the Free Software
894 + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
895 + */
896 +
897 +/*
898 + * Registration for IO processor page table updates.
899 + */
900 +
901 +#include <linux/kernel.h>
902 +#include <linux/module.h>
903 +
904 +#include <linux/mm.h>
905 +#include <linux/ioproc.h>
906 +
907 +int ioproc_register_ops(struct mm_struct *mm, struct ioproc_ops *ip)
908 +{
909 +       ip->next = mm->ioproc_ops;
910 +       mm->ioproc_ops = ip;
911 +
912 +       return 0;
913 +}
914 +
915 +EXPORT_SYMBOL_GPL(ioproc_register_ops);
916 +
917 +int ioproc_unregister_ops(struct mm_struct *mm, struct ioproc_ops *ip)
918 +{
919 +       struct ioproc_ops **tmp;
920 +
921 +       for (tmp = &mm->ioproc_ops; *tmp && *tmp != ip; tmp = &(*tmp)->next) ;
922 +       if (*tmp) {
923 +               *tmp = ip->next;
924 +               return 0;
925 +       }
926 +
927 +       return -EINVAL;
928 +}
929 +
930 +EXPORT_SYMBOL_GPL(ioproc_unregister_ops);
931 Index: linux-269-5502/mm/hugetlb.c
932 ===================================================================
933 --- linux-269-5502.orig/mm/hugetlb.c
934 +++ linux-269-5502/mm/hugetlb.c
935 @@ -10,6 +10,7 @@
936  #include <linux/hugetlb.h>
937  #include <linux/sysctl.h>
938  #include <linux/highmem.h>
939 +#include <linux/ioproc.h>
940  
941  const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
942  static unsigned long nr_huge_pages, free_huge_pages;
943 @@ -260,6 +261,7 @@ void zap_hugepage_range(struct vm_area_s
944         struct mm_struct *mm = vma->vm_mm;
945  
946         spin_lock(&mm->page_table_lock);
947 +       ioproc_invalidate_range(vma, start, start + length);
948         unmap_hugepage_range(vma, start, start + length);
949         spin_unlock(&mm->page_table_lock);
950  }
951 Index: linux-269-5502/mm/Kconfig
952 ===================================================================
953 --- /dev/null
954 +++ linux-269-5502/mm/Kconfig
955 @@ -0,0 +1,15 @@
956 +#
957 +# VM subsystem specific config
958 +# 
959 +
960 +# Support for IO processors which have advanced RDMA capabilities
961 +#
962 +config IOPROC
963 +       bool "Enable IOPROC VM hooks"
964 +       depends on MMU
965 +       default y
966 +       help
967 +       This option enables hooks in the VM subsystem so that IO devices which
968 +       incorporate advanced RDMA capabilities can be kept in sync with CPU 
969 +       page table changes.
970 +       See Documentation/vm/ioproc.txt for more details.
971 Index: linux-269-5502/mm/Makefile
972 ===================================================================
973 --- linux-269-5502.orig/mm/Makefile
974 +++ linux-269-5502/mm/Makefile
975 @@ -16,6 +16,7 @@ obj-$(CONFIG_SWAP)    += page_io.o swap_sta
976  obj-$(CONFIG_X86_4G)   += usercopy.o
977  obj-$(CONFIG_HUGETLBFS)        += hugetlb.o
978  obj-$(CONFIG_NUMA)     += mempolicy.o
979 +obj-$(CONFIG_IOPROC)    += ioproc.o
980  obj-$(CONFIG_SHMEM) += shmem.o
981  obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
982  
983 Index: linux-269-5502/mm/mprotect.c
984 ===================================================================
985 --- linux-269-5502.orig/mm/mprotect.c
986 +++ linux-269-5502/mm/mprotect.c
987 @@ -10,6 +10,7 @@
988  
989  #include <linux/mm.h>
990  #include <linux/hugetlb.h>
991 +#include <linux/ioproc.h>
992  #include <linux/slab.h>
993  #include <linux/shm.h>
994  #include <linux/mman.h>
995 @@ -100,6 +101,7 @@ change_protection(struct vm_area_struct 
996         if (start >= end)
997                 BUG();
998         spin_lock(&current->mm->page_table_lock);
999 +       ioproc_change_protection(vma, start, end, newprot);
1000         do {
1001                 change_pmd_range(dir, start, end - start, newprot);
1002                 start = (start + PGDIR_SIZE) & PGDIR_MASK;
1003 Index: linux-269-5502/mm/msync.c
1004 ===================================================================
1005 --- linux-269-5502.orig/mm/msync.c
1006 +++ linux-269-5502/mm/msync.c
1007 @@ -12,6 +12,7 @@
1008  #include <linux/mm.h>
1009  #include <linux/mman.h>
1010  #include <linux/hugetlb.h>
1011 +#include <linux/ioproc.h>
1012  
1013  #include <asm/pgtable.h>
1014  #include <asm/tlbflush.h>
1015 @@ -115,6 +116,7 @@ static int filemap_sync(struct vm_area_s
1016  
1017         if (address >= end)
1018                 BUG();
1019 +       ioproc_sync_range(vma, address, end);
1020         do {
1021                 error |= filemap_sync_pmd_range(dir, address, end, vma, flags);
1022                 address = (address + PGDIR_SIZE) & PGDIR_MASK;
1023 Index: linux-269-5502/mm/mremap.c
1024 ===================================================================
1025 --- linux-269-5502.orig/mm/mremap.c
1026 +++ linux-269-5502/mm/mremap.c
1027 @@ -9,6 +9,7 @@
1028  
1029  #include <linux/mm.h>
1030  #include <linux/hugetlb.h>
1031 +#include <linux/ioproc.h>
1032  #include <linux/slab.h>
1033  #include <linux/shm.h>
1034  #include <linux/mman.h>
1035 @@ -148,6 +149,8 @@ static unsigned long move_page_tables(st
1036  {
1037         unsigned long offset;
1038  
1039 +       ioproc_invalidate_range(vma, old_addr, old_addr + len);
1040 +       ioproc_invalidate_range(vma, new_addr, new_addr + len);
1041         flush_cache_range(vma, old_addr, old_addr + len);
1042  
1043         /*
1044 Index: linux-269-5502/mm/fremap.c
1045 ===================================================================
1046 --- linux-269-5502.orig/mm/fremap.c
1047 +++ linux-269-5502/mm/fremap.c
1048 @@ -12,6 +12,7 @@
1049  #include <linux/mman.h>
1050  #include <linux/pagemap.h>
1051  #include <linux/swapops.h>
1052 +#include <linux/ioproc.h>
1053  #include <linux/rmap.h>
1054  #include <linux/module.h>
1055  
1056 @@ -29,6 +30,7 @@ static inline void zap_pte(struct mm_str
1057         if (pte_present(pte)) {
1058                 unsigned long pfn = pte_pfn(pte);
1059  
1060 +               ioproc_invalidate_page(vma, addr);
1061                 flush_cache_page(vma, addr);
1062                 pte = ptep_clear_flush(vma, addr, ptep);
1063                 if (pfn_valid(pfn)) {
1064 @@ -93,6 +95,7 @@ int install_page(struct mm_struct *mm, s
1065         pte_val = *pte;
1066         pte_unmap(pte);
1067         update_mmu_cache(vma, addr, pte_val);
1068 +       ioproc_update_page(vma, addr);
1069  
1070         err = 0;
1071  err_unlock:
1072 @@ -132,6 +135,7 @@ int install_file_pte(struct mm_struct *m
1073         pte_val = *pte;
1074         pte_unmap(pte);
1075         update_mmu_cache(vma, addr, pte_val);
1076 +       ioproc_update_page(vma, addr);
1077         spin_unlock(&mm->page_table_lock);
1078         return 0;
1079  
1080 Index: linux-269-5502/mm/rmap.c
1081 ===================================================================
1082 --- linux-269-5502.orig/mm/rmap.c
1083 +++ linux-269-5502/mm/rmap.c
1084 @@ -51,6 +51,7 @@
1085  #include <linux/slab.h>
1086  #include <linux/init.h>
1087  #include <linux/rmap.h>
1088 +#include <linux/ioproc.h>
1089  #include <linux/rcupdate.h>
1090  
1091  #include <asm/tlbflush.h>
1092 @@ -566,6 +567,7 @@ static int try_to_unmap_one(struct page 
1093         }
1094  
1095         /* Nuke the page table entry. */
1096 +       ioproc_invalidate_page(vma, address);
1097         flush_cache_page(vma, address);
1098         pteval = ptep_clear_flush(vma, address, pte);
1099  
1100 @@ -673,6 +675,7 @@ static void try_to_unmap_cluster(unsigne
1101                         continue;
1102  
1103                 /* Nuke the page table entry. */
1104 +               ioproc_invalidate_page(vma, address);
1105                 flush_cache_page(vma, address);
1106                 pteval = ptep_clear_flush(vma, address, pte);
1107  
1108 Index: linux-269-5502/mm/memory.c
1109 ===================================================================
1110 --- linux-269-5502.orig/mm/memory.c
1111 +++ linux-269-5502/mm/memory.c
1112 @@ -43,6 +43,7 @@
1113  #include <linux/swap.h>
1114  #include <linux/highmem.h>
1115  #include <linux/pagemap.h>
1116 +#include <linux/ioproc.h>
1117  #include <linux/rmap.h>
1118  #include <linux/module.h>
1119  #include <linux/init.h>
1120 @@ -630,6 +631,7 @@ void zap_page_range(struct vm_area_struc
1121  
1122         lru_add_drain();
1123         spin_lock(&mm->page_table_lock);
1124 +       ioproc_invalidate_range(vma, address, end);
1125         tlb = tlb_gather_mmu(mm, 0);
1126         unmap_vmas(&tlb, mm, vma, address, end, &nr_accounted, details);
1127         tlb_finish_mmu(tlb, address, end);
1128 @@ -998,6 +1000,7 @@ int zeromap_page_range(struct vm_area_st
1129                 BUG();
1130  
1131         spin_lock(&mm->page_table_lock);
1132 +       ioproc_invalidate_range(vma, beg, end);
1133         do {
1134                 pmd_t *pmd = pmd_alloc(mm, dir, address);
1135                 error = -ENOMEM;
1136 @@ -1012,6 +1015,7 @@ int zeromap_page_range(struct vm_area_st
1137         /*
1138          * Why flush? zeromap_pte_range has a BUG_ON for !pte_none()
1139          */
1140 +       ioproc_update_range(vma, beg, end);
1141         flush_tlb_range(vma, beg, end);
1142         spin_unlock(&mm->page_table_lock);
1143         return error;
1144 @@ -1092,6 +1096,7 @@ int remap_page_range(struct vm_area_stru
1145         vma->vm_flags |= VM_IO | VM_RESERVED;
1146  
1147         spin_lock(&mm->page_table_lock);
1148 +       ioproc_invalidate_range(vma, beg, end);
1149         do {
1150                 pmd_t *pmd = pmd_alloc(mm, dir, from);
1151                 error = -ENOMEM;
1152 @@ -1106,6 +1111,7 @@ int remap_page_range(struct vm_area_stru
1153         /*
1154          * Why flush? remap_pte_range has a BUG_ON for !pte_none()
1155          */
1156 +       ioproc_update_range(vma, beg, end);
1157         flush_tlb_range(vma, beg, end);
1158         spin_unlock(&mm->page_table_lock);
1159         return error;
1160 @@ -1194,6 +1200,7 @@ static int do_wp_page(struct mm_struct *
1161                         update_mmu_cache(vma, address, entry);
1162                         lazy_mmu_prot_update(entry);
1163                         pte_unmap(page_table);
1164 +                       ioproc_update_page(vma, address);
1165                         spin_unlock(&mm->page_table_lock);
1166                         return VM_FAULT_MINOR;
1167                 }
1168 @@ -1226,6 +1233,7 @@ static int do_wp_page(struct mm_struct *
1169                         ++mm->rss;
1170                 else
1171                         page_remove_rmap(old_page);
1172 +               ioproc_invalidate_page(vma, address);
1173                 break_cow(vma, new_page, address, page_table);
1174                 lru_cache_add_active(new_page);
1175                 page_add_anon_rmap(new_page, vma, address);
1176 @@ -1234,6 +1242,7 @@ static int do_wp_page(struct mm_struct *
1177                 new_page = old_page;
1178         }
1179         pte_unmap(page_table);
1180 +       ioproc_update_page(vma, address);
1181         page_cache_release(new_page);
1182         page_cache_release(old_page);
1183         spin_unlock(&mm->page_table_lock);
1184 @@ -1630,6 +1639,7 @@ static int do_swap_page(struct mm_struct
1185         update_mmu_cache(vma, address, pte);
1186         lazy_mmu_prot_update(pte);
1187         pte_unmap(page_table);
1188 +       ioproc_update_page(vma, address);
1189         spin_unlock(&mm->page_table_lock);
1190  out:
1191         return ret;
1192 @@ -1695,6 +1705,7 @@ do_anonymous_page(struct mm_struct *mm, 
1193         /* No need to invalidate - it was non-present before */
1194         update_mmu_cache(vma, addr, entry);
1195         lazy_mmu_prot_update(entry);
1196 +       ioproc_update_page(vma, addr);
1197         spin_unlock(&mm->page_table_lock);
1198  out:
1199         return VM_FAULT_MINOR;
1200 @@ -1813,6 +1824,7 @@ retry:
1201  
1202         /* no need to invalidate: a not-present page shouldn't be cached */
1203         update_mmu_cache(vma, address, entry);
1204 +       ioproc_update_page(vma, address);
1205         spin_unlock(&mm->page_table_lock);
1206  out:
1207         return ret;
1208 @@ -1998,6 +2010,7 @@ int make_pages_present(unsigned long add
1209                 return ret;
1210         return ret == len ? 0 : -1;
1211  }
1212 +EXPORT_SYMBOL(make_pages_present);
1213  
1214  /* 
1215   * Map a vmalloc()-space virtual address to the physical page.
1216 Index: linux-269-5502/mm/mmap.c
1217 ===================================================================
1218 --- linux-269-5502.orig/mm/mmap.c
1219 +++ linux-269-5502/mm/mmap.c
1220 @@ -15,6 +15,7 @@
1221  #include <linux/init.h>
1222  #include <linux/file.h>
1223  #include <linux/fs.h>
1224 +#include <linux/ioproc.h>
1225  #include <linux/personality.h>
1226  #include <linux/security.h>
1227  #include <linux/hugetlb.h>
1228 @@ -1703,6 +1704,7 @@ static void unmap_region(struct mm_struc
1229         unsigned long nr_accounted = 0;
1230  
1231         lru_add_drain();
1232 +       ioproc_invalidate_range(vma, start, end);
1233         tlb = tlb_gather_mmu(mm, 0);
1234         unmap_vmas(&tlb, mm, vma, start, end, &nr_accounted, NULL);
1235         vm_unacct_memory(nr_accounted);
1236 @@ -1995,6 +1997,7 @@ void exit_mmap(struct mm_struct *mm)
1237  
1238         spin_lock(&mm->page_table_lock);
1239  
1240 +       ioproc_release(mm);
1241         tlb = tlb_gather_mmu(mm, 1);
1242         flush_cache_mm(mm);
1243         /* Use ~0UL here to ensure all VMAs in the mm are unmapped */
1244 Index: linux-269-5502/ipc/shm.c
1245 ===================================================================
1246 --- linux-269-5502.orig/ipc/shm.c
1247 +++ linux-269-5502/ipc/shm.c
1248 @@ -26,6 +26,7 @@
1249  #include <linux/proc_fs.h>
1250  #include <linux/shmem_fs.h>
1251  #include <linux/security.h>
1252 +#include <linux/module.h>
1253  #include <linux/audit.h>
1254  #include <asm/uaccess.h>
1255  
1256 @@ -856,6 +857,44 @@ asmlinkage long sys_shmdt(char __user *s
1257         return retval;
1258  }
1259  
1260 +/*
1261 + * Mark all segments created by this process for destruction
1262 + */
1263 +int shm_cleanup (void)
1264 +{
1265 +       int i;
1266 +
1267 +       down(&shm_ids.sem);
1268 +
1269 +       for (i = 0; i <= shm_ids.max_id; i++) {
1270 +               struct shmid_kernel *shp;
1271 +
1272 +               shp = shm_lock(i);
1273 +               if (shp != NULL) {
1274 +                       /* mark this segment for destruction if we created it */
1275 +                       if (current->pid == shp->shm_cprid)
1276 +                       {
1277 +                               /* copy of IPC_RMID code */
1278 +                               if (shp->shm_nattch) {
1279 +                                       shp->shm_flags |= SHM_DEST;
1280 +                                       /* do not find it any more */
1281 +                                       shp->shm_perm.key = IPC_PRIVATE;
1282 +                               } else {
1283 +                                       shm_destroy(shp);
1284 +                                       continue;
1285 +                               }
1286 +                       }
1287 +
1288 +                       shm_unlock(shp);
1289 +               }
1290 +       }
1291 +
1292 +       up(&shm_ids.sem);
1293 +
1294 +       return 0;
1295 +}
1296 +EXPORT_SYMBOL_GPL(shm_cleanup);
1297 +
1298  #ifdef CONFIG_PROC_FS
1299  static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
1300  {
1301 Index: linux-269-5502/include/linux/init_task.h
1302 ===================================================================
1303 --- linux-269-5502.orig/include/linux/init_task.h
1304 +++ linux-269-5502/include/linux/init_task.h
1305 @@ -2,6 +2,7 @@
1306  #define _LINUX__INIT_TASK_H
1307  
1308  #include <linux/file.h>
1309 +#include <linux/ptrack.h>
1310  
1311  #define INIT_FILES \
1312  {                                                      \
1313 @@ -112,6 +113,7 @@ extern struct group_info init_groups;
1314         .proc_lock      = SPIN_LOCK_UNLOCKED,                           \
1315         .switch_lock    = SPIN_LOCK_UNLOCKED,                           \
1316         .journal_info   = NULL,                                         \
1317 +       INIT_TASK_PTRACK(tsk)                                           \
1318  }
1319  
1320  
1321 Index: linux-269-5502/include/linux/ioproc.h
1322 ===================================================================
1323 --- /dev/null
1324 +++ linux-269-5502/include/linux/ioproc.h
1325 @@ -0,0 +1,270 @@
1326 +/*
1327 + *    Copyright (C) 2006 Quadrics Ltd
1328 + *
1329 + *    This program is free software; you can redistribute it and/or modify
1330 + *    it under the terms of the GNU General Public License as published by
1331 + *    the Free Software Foundation; either version 2 of the License, or
1332 + *    (at your option) any later version.
1333 + *
1334 + *    This program is distributed in the hope that it will be useful,
1335 + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
1336 + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1337 + *    GNU General Public License for more details.
1338 + *
1339 + *    You should have received a copy of the GNU General Public License
1340 + *    along with this program; if not, write to the Free Software
1341 + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1342 + */
1343 +
1344 +/*
1345 + * Callbacks for IO processor page table updates.
1346 + */
1347 +
1348 +#ifndef __LINUX_IOPROC_H__
1349 +#define __LINUX_IOPROC_H__
1350 +
1351 +#include <linux/sched.h>
1352 +#include <linux/mm.h>
1353 +
1354 +typedef struct ioproc_ops {
1355 +       struct ioproc_ops *next;
1356 +       void *arg;
1357 +
1358 +       void (*release) (void *arg, struct mm_struct * mm);
1359 +       void (*sync_range) (void *arg, struct vm_area_struct * vma,
1360 +                           unsigned long start, unsigned long end);
1361 +       void (*invalidate_range) (void *arg, struct vm_area_struct * vma,
1362 +                                 unsigned long start, unsigned long end);
1363 +       void (*update_range) (void *arg, struct vm_area_struct * vma,
1364 +                             unsigned long start, unsigned long end);
1365 +
1366 +       void (*change_protection) (void *arg, struct vm_area_struct * vma,
1367 +                                  unsigned long start, unsigned long end,
1368 +                                  pgprot_t newprot);
1369 +
1370 +       void (*sync_page) (void *arg, struct vm_area_struct * vma,
1371 +                          unsigned long address);
1372 +       void (*invalidate_page) (void *arg, struct vm_area_struct * vma,
1373 +                                unsigned long address);
1374 +       void (*update_page) (void *arg, struct vm_area_struct * vma,
1375 +                            unsigned long address);
1376 +
1377 +} ioproc_ops_t;
1378 +
1379 +/* IOPROC Registration
1380 + * 
1381 + * Called by the IOPROC device driver to register its interest in page table
1382 + * changes for the process associated with the supplied mm_struct
1383 + *
1384 + * The caller should first allocate and fill out an ioproc_ops structure with 
1385 + * the function pointers initialised to the device driver specific code for
1386 + * each callback. If the device driver doesn't have code for a particular 
1387 + * callback then it should set the function pointer to be NULL.
1388 + * The ioproc_ops arg parameter will be passed unchanged as the first argument
1389 + * to each callback function invocation.
1390 + *
1391 + * The ioproc registration is not inherited across fork() and should be called
1392 + * once for each process that the IOPROC device driver is interested in.
1393 + *
1394 + * Must be called holding the mm->page_table_lock
1395 + */
1396 +extern int ioproc_register_ops(struct mm_struct *mm, struct ioproc_ops *ip);
1397 +
1398 +/* IOPROC De-registration
1399 + * 
1400 + * Called by the IOPROC device driver when it is no longer interested in page 
1401 + * table changes for the process associated with the supplied mm_struct
1402 + *
1403 + * Normally this is not needed to be called as the ioproc_release() code will
1404 + * automatically unlink the ioproc_ops struct from the mm_struct as the
1405 + * process exits
1406 + *
1407 + * Must be called holding the mm->page_table_lock
1408 + */
1409 +extern int ioproc_unregister_ops(struct mm_struct *mm, struct ioproc_ops *ip);
1410 +
1411 +#ifdef CONFIG_IOPROC
1412 +
1413 +/* IOPROC Release
1414 + *
1415 + * Called during exit_mmap() as all vmas are torn down and unmapped.
1416 + *
1417 + * Also unlinks the ioproc_ops structure from the mm list as it goes.
1418 + *
1419 + * No need for locks as the mm can no longer be accessed at this point
1420 + *
1421 + */
1422 +static inline void ioproc_release(struct mm_struct *mm)
1423 +{
1424 +       struct ioproc_ops *cp;
1425 +
1426 +       while ((cp = mm->ioproc_ops) != NULL) {
1427 +               mm->ioproc_ops = cp->next;
1428 +
1429 +               if (cp->release)
1430 +                       cp->release(cp->arg, mm);
1431 +       }
1432 +}
1433 +
1434 +/* IOPROC SYNC RANGE
1435 + *
1436 + * Called when a memory map is synchronised with its disk image i.e. when the 
1437 + * msync() syscall is invoked. Any future read or write to the associated 
1438 + * pages by the IOPROC should cause the page to be marked as referenced or 
1439 + * modified.
1440 + *
1441 + * Called holding the mm->page_table_lock
1442 + */
1443 +static inline void
1444 +ioproc_sync_range(struct vm_area_struct *vma, unsigned long start,
1445 +                 unsigned long end)
1446 +{
1447 +       struct ioproc_ops *cp;
1448 +
1449 +       for (cp = vma->vm_mm->ioproc_ops; cp; cp = cp->next)
1450 +               if (cp->sync_range)
1451 +                       cp->sync_range(cp->arg, vma, start, end);
1452 +}
1453 +
1454 +/* IOPROC INVALIDATE RANGE
1455 + *
1456 + * Called whenever a valid PTE is unloaded e.g. when a page is unmapped by the
1457 + * user or paged out by the kernel. 
1458 + *
1459 + * After this call the IOPROC must not access the physical memory again unless
1460 + * a new translation is loaded.
1461 + *
1462 + * Called holding the mm->page_table_lock
1463 + */
1464 +static inline void
1465 +ioproc_invalidate_range(struct vm_area_struct *vma, unsigned long start,
1466 +                       unsigned long end)
1467 +{
1468 +       struct ioproc_ops *cp;
1469 +
1470 +       for (cp = vma->vm_mm->ioproc_ops; cp; cp = cp->next)
1471 +               if (cp->invalidate_range)
1472 +                       cp->invalidate_range(cp->arg, vma, start, end);
1473 +}
1474 +
1475 +/* IOPROC UPDATE RANGE
1476 + *
1477 + * Called whenever a valid PTE is loaded e.g. mmaping memory, moving the brk 
1478 + * up, when breaking COW or faulting in an anonymous page of memory.
1479 + *
1480 + * These give the IOPROC device driver the opportunity to load translations 
1481 + * speculatively, which can improve performance by avoiding device translation
1482 + * faults.
1483 + *
1484 + * Called holding the mm->page_table_lock
1485 + */
1486 +static inline void
1487 +ioproc_update_range(struct vm_area_struct *vma, unsigned long start,
1488 +                   unsigned long end)
1489 +{
1490 +       struct ioproc_ops *cp;
1491 +
1492 +       for (cp = vma->vm_mm->ioproc_ops; cp; cp = cp->next)
1493 +               if (cp->update_range)
1494 +                       cp->update_range(cp->arg, vma, start, end);
1495 +}
1496 +
1497 +/* IOPROC CHANGE PROTECTION
1498 + *
1499 + * Called when the protection on a region of memory is changed i.e. when the 
1500 + * mprotect() syscall is invoked.
1501 + *
1502 + * The IOPROC must not be able to write to a read-only page, so if the 
1503 + * permissions are downgraded then it must honour them. If they are upgraded 
1504 + * it can treat this in the same way as the ioproc_update_[range|sync]() calls
1505 + *
1506 + * Called holding the mm->page_table_lock
1507 + */
1508 +static inline void
1509 +ioproc_change_protection(struct vm_area_struct *vma, unsigned long start,
1510 +                        unsigned long end, pgprot_t newprot)
1511 +{
1512 +       struct ioproc_ops *cp;
1513 +
1514 +       for (cp = vma->vm_mm->ioproc_ops; cp; cp = cp->next)
1515 +               if (cp->change_protection)
1516 +                       cp->change_protection(cp->arg, vma, start, end,
1517 +                                             newprot);
1518 +}
1519 +
1520 +/* IOPROC SYNC PAGE
1521 + *
1522 + * Called when a memory map is synchronised with its disk image i.e. when the 
1523 + * msync() syscall is invoked. Any future read or write to the associated page
1524 + * by the IOPROC should cause the page to be marked as referenced or modified.
1525 + *
1526 + * Not currently called as msync() calls ioproc_sync_range() instead
1527 + *
1528 + * Called holding the mm->page_table_lock
1529 + */
1530 +static inline void
1531 +ioproc_sync_page(struct vm_area_struct *vma, unsigned long addr)
1532 +{
1533 +       struct ioproc_ops *cp;
1534 +
1535 +       for (cp = vma->vm_mm->ioproc_ops; cp; cp = cp->next)
1536 +               if (cp->sync_page)
1537 +                       cp->sync_page(cp->arg, vma, addr);
1538 +}
1539 +
1540 +/* IOPROC INVALIDATE PAGE
1541 + *
1542 + * Called whenever a valid PTE is unloaded e.g. when a page is unmapped by the
1543 + * user or paged out by the kernel. 
1544 + *
1545 + * After this call the IOPROC must not access the physical memory again unless
1546 + * a new translation is loaded.
1547 + *
1548 + * Called holding the mm->page_table_lock
1549 + */
1550 +static inline void
1551 +ioproc_invalidate_page(struct vm_area_struct *vma, unsigned long addr)
1552 +{
1553 +       struct ioproc_ops *cp;
1554 +
1555 +       for (cp = vma->vm_mm->ioproc_ops; cp; cp = cp->next)
1556 +               if (cp->invalidate_page)
1557 +                       cp->invalidate_page(cp->arg, vma, addr);
1558 +}
1559 +
1560 +/* IOPROC UPDATE PAGE
1561 + *
1562 + * Called whenever a valid PTE is loaded e.g. mmaping memory, moving the brk 
1563 + * up, when breaking COW or faulting in an anoymous page of memory.
1564 + *
1565 + * These give the IOPROC device the opportunity to load translations 
1566 + * speculatively, which can improve performance by avoiding device translation
1567 + * faults.
1568 + *
1569 + * Called holding the mm->page_table_lock
1570 + */
1571 +static inline void
1572 +ioproc_update_page(struct vm_area_struct *vma, unsigned long addr)
1573 +{
1574 +       struct ioproc_ops *cp;
1575 +
1576 +       for (cp = vma->vm_mm->ioproc_ops; cp; cp = cp->next)
1577 +               if (cp->update_page)
1578 +                       cp->update_page(cp->arg, vma, addr);
1579 +}
1580 +
1581 +#else
1582 +
1583 +/* ! CONFIG_IOPROC so make all hooks empty */
1584 +
1585 +#define ioproc_release(mm)                             do { } while (0)
1586 +#define ioproc_sync_range(vma, start, end)             do { } while (0)
1587 +#define ioproc_invalidate_range(vma, start, end)       do { } while (0)
1588 +#define ioproc_update_range(vma, start, end)           do { } while (0)
1589 +#define ioproc_change_protection(vma, start, end, prot)        do { } while (0)
1590 +#define ioproc_sync_page(vma, addr)                    do { } while (0)
1591 +#define ioproc_invalidate_page(vma, addr)              do { } while (0)
1592 +#define ioproc_update_page(vma, addr)                  do { } while (0)
1593 +
1594 +#endif                         /* CONFIG_IOPROC */
1595 +#endif                         /* __LINUX_IOPROC_H__ */
1596 Index: linux-269-5502/include/linux/sched.h
1597 ===================================================================
1598 --- linux-269-5502.orig/include/linux/sched.h
1599 +++ linux-269-5502/include/linux/sched.h
1600 @@ -185,6 +185,9 @@ extern signed long schedule_timeout_unin
1601  asmlinkage void schedule(void);
1602  
1603  struct namespace;
1604 +#ifdef CONFIG_IOPROC
1605 +struct ioproc_ops;
1606 +#endif
1607  
1608  /* Maximum number of active map areas.. This is a random (large) number */
1609  #define DEFAULT_MAX_MAP_COUNT  65536
1610 @@ -260,6 +263,11 @@ struct mm_struct {
1611         struct kioctx           *ioctx_list;
1612  
1613         struct kioctx           default_kioctx;
1614
1615 +#ifdef CONFIG_IOPROC
1616 +       /* hooks for io devices with advanced RDMA capabilities */
1617 +       struct ioproc_ops       *ioproc_ops;
1618 +#endif
1619  };
1620  
1621  extern int mmlist_nr;
1622 @@ -635,6 +643,10 @@ struct task_struct {
1623         struct mempolicy *mempolicy;
1624         short il_next;          /* could be shared with used_math */
1625  #endif
1626 +#ifdef CONFIG_PTRACK
1627 +/* process tracking callback */
1628 +       struct list_head ptrack_list;
1629 +#endif
1630  };
1631  
1632  static inline pid_t process_group(struct task_struct *tsk)
1633 Index: linux-269-5502/include/linux/ptrack.h
1634 ===================================================================
1635 --- /dev/null
1636 +++ linux-269-5502/include/linux/ptrack.h
1637 @@ -0,0 +1,65 @@
1638 +/*
1639 + *    Copyright (C) 2000  Regents of the University of California
1640 + *
1641 + *    This program is free software; you can redistribute it and/or modify
1642 + *    it under the terms of the GNU General Public License as published by
1643 + *    the Free Software Foundation; either version 2 of the License, or
1644 + *    (at your option) any later version.
1645 + *
1646 + *    This program is distributed in the hope that it will be useful,
1647 + *    but WITHOUT ANY WARRANTY; without even the implied warranty of
1648 + *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1649 + *    GNU General Public License for more details.
1650 + *
1651 + *    You should have received a copy of the GNU General Public License
1652 + *    along with this program; if not, write to the Free Software
1653 + *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1654 + *
1655 + * Derived from exit_actn.c by
1656 + *    Copyright (C) 2003 Quadrics Ltd.
1657 + *
1658 + */
1659 +#ifndef __LINUX_PTRACK_H
1660 +#define __LINUX_PTRACK_H
1661 +
1662 +/* 
1663 + * Process tracking - this allows a module to keep track of processes
1664 + * in order that it can manage all tasks derived from a single process.
1665 + */
1666 +
1667 +#define PTRACK_PHASE_CLONE     1
1668 +#define PTRACK_PHASE_CLONE_FAIL        2
1669 +#define PTRACK_PHASE_EXEC      3
1670 +#define PTRACK_PHASE_EXIT              4
1671 +
1672 +#define PTRACK_FINISHED                0
1673 +#define PTRACK_INNHERIT                1
1674 +#define PTRACK_DENIED          2
1675 +
1676 +#ifdef CONFIG_PTRACK
1677 +
1678 +typedef int (*ptrack_callback_t)(void *arg, int phase, struct task_struct *child);
1679 +
1680 +struct ptrack_desc {
1681 +       struct list_head        link;
1682 +       ptrack_callback_t       callback;
1683 +       void                   *arg;
1684 +};
1685 +
1686 +extern int     ptrack_register (ptrack_callback_t callback, void *arg);
1687 +extern void    ptrack_deregister (ptrack_callback_t callback, void *arg);
1688 +extern int     ptrack_registered (ptrack_callback_t callback, void *arg);
1689 +
1690 +extern int     ptrack_call_callbacks (int phase, struct task_struct *child);
1691 +
1692 +#define INIT_TASK_PTRACK(tsk) \
1693 +       .ptrack_list = LIST_HEAD_INIT(tsk.ptrack_list)
1694 +
1695 +#else
1696 +#define ptrack_call_callbacks (phase, child) (0)
1697 +
1698 +#define INIT_TASK_PTRACK(tsk)
1699 +
1700 +#endif
1701 +
1702 +#endif /* __LINUX_PTRACK_H */
1703 Index: linux-269-5502/include/asm-ia64/param.h
1704 ===================================================================
1705 --- linux-269-5502.orig/include/asm-ia64/param.h
1706 +++ linux-269-5502/include/asm-ia64/param.h
1707 @@ -27,7 +27,7 @@
1708     */
1709  #  define HZ     32
1710  # else
1711 -#  define HZ   1024
1712 +#  define HZ   100
1713  # endif
1714  # define USER_HZ       HZ
1715  # define CLOCKS_PER_SEC        HZ      /* frequency at which times() counts */
1716 Index: linux-269-5502/include/asm-i386/param.h
1717 ===================================================================
1718 --- linux-269-5502.orig/include/asm-i386/param.h
1719 +++ linux-269-5502/include/asm-i386/param.h
1720 @@ -2,7 +2,7 @@
1721  #define _ASMi386_PARAM_H
1722  
1723  #ifdef __KERNEL__
1724 -# define HZ            1000            /* Internal kernel timer frequency */
1725 +# define HZ            100             /* Internal kernel timer frequency */
1726  # define USER_HZ       100             /* .. some user interfaces are in "ticks" */
1727  # define CLOCKS_PER_SEC                (USER_HZ)       /* like times() */
1728  #endif
1729 Index: linux-269-5502/include/asm-x86_64/param.h
1730 ===================================================================
1731 --- linux-269-5502.orig/include/asm-x86_64/param.h
1732 +++ linux-269-5502/include/asm-x86_64/param.h
1733 @@ -2,7 +2,7 @@
1734  #define _ASMx86_64_PARAM_H
1735  
1736  #ifdef __KERNEL__
1737 -# define HZ            1000            /* Internal kernel timer frequency */
1738 +# define HZ            100            /* Internal kernel timer frequency */
1739  # define USER_HZ       100          /* .. some user interfaces are in "ticks */
1740  #define CLOCKS_PER_SEC        (USER_HZ)       /* like times() */
1741  #endif