{
        shm_init_ns(&init_ipc_ns);
        ipc_init_proc_interface("sysvipc/shm",
-                               "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n",
+#if BITS_PER_LONG <= 32
+                               "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime        rss       swap\n",
+#else
+                               "       key      shmid perms                  size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime                   rss                  swap\n",
+#endif
                                IPC_SHM_IDS, sysvipc_shm_proc_show);
 }
 
        }
 }
 
+/*
+ * Calculate and add used RSS and swap pages of a shm.
+ * Called with shm_ids.rw_mutex held as a reader
+ */
+static void shm_add_rss_swap(struct shmid_kernel *shp,
+       unsigned long *rss_add, unsigned long *swp_add)
+{
+       struct inode *inode;
+
+       inode = shp->shm_file->f_path.dentry->d_inode;
+
+       if (is_file_hugepages(shp->shm_file)) {
+               struct address_space *mapping = inode->i_mapping;
+               struct hstate *h = hstate_file(shp->shm_file);
+               *rss_add += pages_per_huge_page(h) * mapping->nrpages;
+       } else {
+#ifdef CONFIG_SHMEM
+               struct shmem_inode_info *info = SHMEM_I(inode);
+               spin_lock(&info->lock);
+               *rss_add += inode->i_mapping->nrpages;
+               *swp_add += info->swapped;
+               spin_unlock(&info->lock);
+#else
+               *rss_add += inode->i_mapping->nrpages;
+#endif
+       }
+}
+
 /*
  * Called with shm_ids.rw_mutex held as a reader
  */
        for (total = 0, next_id = 0; total < in_use; next_id++) {
                struct kern_ipc_perm *ipc;
                struct shmid_kernel *shp;
-               struct inode *inode;
 
                ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id);
                if (ipc == NULL)
                        continue;
                shp = container_of(ipc, struct shmid_kernel, shm_perm);
 
-               inode = shp->shm_file->f_path.dentry->d_inode;
-
-               if (is_file_hugepages(shp->shm_file)) {
-                       struct address_space *mapping = inode->i_mapping;
-                       struct hstate *h = hstate_file(shp->shm_file);
-                       *rss += pages_per_huge_page(h) * mapping->nrpages;
-               } else {
-#ifdef CONFIG_SHMEM
-                       struct shmem_inode_info *info = SHMEM_I(inode);
-                       spin_lock(&info->lock);
-                       *rss += inode->i_mapping->nrpages;
-                       *swp += info->swapped;
-                       spin_unlock(&info->lock);
-#else
-                       *rss += inode->i_mapping->nrpages;
-#endif
-               }
+               shm_add_rss_swap(shp, rss, swp);
 
                total++;
        }
 static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
 {
        struct shmid_kernel *shp = it;
+       unsigned long rss = 0, swp = 0;
+
+       shm_add_rss_swap(shp, &rss, &swp);
 
 #if BITS_PER_LONG <= 32
 #define SIZE_SPEC "%10lu"
 
        return seq_printf(s,
                          "%10d %10d  %4o " SIZE_SPEC " %5u %5u  "
-                         "%5lu %5u %5u %5u %5u %10lu %10lu %10lu\n",
+                         "%5lu %5u %5u %5u %5u %10lu %10lu %10lu "
+                         SIZE_SPEC " " SIZE_SPEC "\n",
                          shp->shm_perm.key,
                          shp->shm_perm.id,
                          shp->shm_perm.mode,
                          shp->shm_perm.cgid,
                          shp->shm_atim,
                          shp->shm_dtim,
-                         shp->shm_ctim);
+                         shp->shm_ctim,
+                         rss * PAGE_SIZE,
+                         swp * PAGE_SIZE);
 }
 #endif