struct super_block;
 extern void acct_auto_close_mnt(struct vfsmount *m);
 extern void acct_auto_close(struct super_block *sb);
+extern void acct_init_pacct(struct pacct_struct *pacct);
+extern void acct_collect();
 extern void acct_process(long exitcode);
 extern void acct_update_integrals(struct task_struct *tsk);
 extern void acct_clear_integrals(struct task_struct *tsk);
 #else
 #define acct_auto_close_mnt(x) do { } while (0)
 #define acct_auto_close(x)     do { } while (0)
+#define acct_init_pacct(x)     do { } while (0)
+#define acct_collect()         do { } while (0)
 #define acct_process(x)                do { } while (0)
 #define acct_update_integrals(x)               do { } while (0)
 #define acct_clear_integrals(task)     do { } while (0)
 
        spinlock_t              siglock;
 };
 
+struct pacct_struct {
+       unsigned long           ac_mem;
+};
+
 /*
  * NOTE! "signal_struct" does not have it's own
  * locking, because a shared signal_struct always
        struct key *session_keyring;    /* keyring inherited over fork */
        struct key *process_keyring;    /* keyring private to this process */
 #endif
+#ifdef CONFIG_BSD_PROCESS_ACCT
+       struct pacct_struct pacct;      /* per-process accounting information */
+#endif
 };
 
 /* Context switch must be unlocked if interrupts are to be enabled */
 
  */
 static void do_acct_process(long exitcode, struct file *file)
 {
+       struct pacct_struct *pacct = ¤t->signal->pacct;
        acct_t ac;
        mm_segment_t fs;
-       unsigned long vsize;
        unsigned long flim;
        u64 elapsed;
        u64 run_time;
                ac.ac_flag |= ACORE;
        if (current->flags & PF_SIGNALED)
                ac.ac_flag |= AXSIG;
-
-       vsize = 0;
-       if (current->mm) {
-               struct vm_area_struct *vma;
-               down_read(¤t->mm->mmap_sem);
-               vma = current->mm->mmap;
-               while (vma) {
-                       vsize += vma->vm_end - vma->vm_start;
-                       vma = vma->vm_next;
-               }
-               up_read(¤t->mm->mmap_sem);
-       }
-       vsize = vsize / 1024;
-       ac.ac_mem = encode_comp_t(vsize);
+       spin_lock(¤t->sighand->siglock);
+       ac.ac_mem = encode_comp_t(pacct->ac_mem);
+       spin_unlock(¤t->sighand->siglock);
        ac.ac_io = encode_comp_t(0 /* current->io_usage */);    /* %% */
        ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
        ac.ac_minflt = encode_comp_t(current->signal->min_flt +
        set_fs(fs);
 }
 
+/**
+ * acct_init_pacct - initialize a new pacct_struct
+ */
+void acct_init_pacct(struct pacct_struct *pacct)
+{
+       memset(pacct, 0, sizeof(struct pacct_struct));
+}
+
+/**
+ * acct_collect - collect accounting information into pacct_struct
+ */
+void acct_collect(void)
+{
+       struct pacct_struct *pacct = ¤t->signal->pacct;
+       unsigned long vsize = 0;
+
+       if (current->mm) {
+               struct vm_area_struct *vma;
+               down_read(¤t->mm->mmap_sem);
+               vma = current->mm->mmap;
+               while (vma) {
+                       vsize += vma->vm_end - vma->vm_start;
+                       vma = vma->vm_next;
+               }
+               up_read(¤t->mm->mmap_sem);
+       }
+
+       spin_lock(¤t->sighand->siglock);
+       pacct->ac_mem = vsize / 1024;
+       spin_unlock(¤t->sighand->siglock);
+}
+
 /**
  * acct_process - now just a wrapper around do_acct_process
  * @exitcode: task exit code