aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipc/shm.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index 7bc46a9fe1f8..fd658a1c2b88 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -108,7 +108,11 @@ void __init shm_init (void)
108{ 108{
109 shm_init_ns(&init_ipc_ns); 109 shm_init_ns(&init_ipc_ns);
110 ipc_init_proc_interface("sysvipc/shm", 110 ipc_init_proc_interface("sysvipc/shm",
111 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime\n", 111#if BITS_PER_LONG <= 32
112 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
113#else
114 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n",
115#endif
112 IPC_SHM_IDS, sysvipc_shm_proc_show); 116 IPC_SHM_IDS, sysvipc_shm_proc_show);
113} 117}
114 118
@@ -544,6 +548,34 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
544} 548}
545 549
546/* 550/*
551 * Calculate and add used RSS and swap pages of a shm.
552 * Called with shm_ids.rw_mutex held as a reader
553 */
554static void shm_add_rss_swap(struct shmid_kernel *shp,
555 unsigned long *rss_add, unsigned long *swp_add)
556{
557 struct inode *inode;
558
559 inode = shp->shm_file->f_path.dentry->d_inode;
560
561 if (is_file_hugepages(shp->shm_file)) {
562 struct address_space *mapping = inode->i_mapping;
563 struct hstate *h = hstate_file(shp->shm_file);
564 *rss_add += pages_per_huge_page(h) * mapping->nrpages;
565 } else {
566#ifdef CONFIG_SHMEM
567 struct shmem_inode_info *info = SHMEM_I(inode);
568 spin_lock(&info->lock);
569 *rss_add += inode->i_mapping->nrpages;
570 *swp_add += info->swapped;
571 spin_unlock(&info->lock);
572#else
573 *rss_add += inode->i_mapping->nrpages;
574#endif
575 }
576}
577
578/*
547 * Called with shm_ids.rw_mutex held as a reader 579 * Called with shm_ids.rw_mutex held as a reader
548 */ 580 */
549static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, 581static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
@@ -560,30 +592,13 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
560 for (total = 0, next_id = 0; total < in_use; next_id++) { 592 for (total = 0, next_id = 0; total < in_use; next_id++) {
561 struct kern_ipc_perm *ipc; 593 struct kern_ipc_perm *ipc;
562 struct shmid_kernel *shp; 594 struct shmid_kernel *shp;
563 struct inode *inode;
564 595
565 ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id); 596 ipc = idr_find(&shm_ids(ns).ipcs_idr, next_id);
566 if (ipc == NULL) 597 if (ipc == NULL)
567 continue; 598 continue;
568 shp = container_of(ipc, struct shmid_kernel, shm_perm); 599 shp = container_of(ipc, struct shmid_kernel, shm_perm);
569 600
570 inode = shp->shm_file->f_path.dentry->d_inode; 601 shm_add_rss_swap(shp, rss, swp);
571
572 if (is_file_hugepages(shp->shm_file)) {
573 struct address_space *mapping = inode->i_mapping;
574 struct hstate *h = hstate_file(shp->shm_file);
575 *rss += pages_per_huge_page(h) * mapping->nrpages;
576 } else {
577#ifdef CONFIG_SHMEM
578 struct shmem_inode_info *info = SHMEM_I(inode);
579 spin_lock(&info->lock);
580 *rss += inode->i_mapping->nrpages;
581 *swp += info->swapped;
582 spin_unlock(&info->lock);
583#else
584 *rss += inode->i_mapping->nrpages;
585#endif
586 }
587 602
588 total++; 603 total++;
589 } 604 }
@@ -1072,6 +1087,9 @@ SYSCALL_DEFINE1(shmdt, char __user *, shmaddr)
1072static int sysvipc_shm_proc_show(struct seq_file *s, void *it) 1087static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
1073{ 1088{
1074 struct shmid_kernel *shp = it; 1089 struct shmid_kernel *shp = it;
1090 unsigned long rss = 0, swp = 0;
1091
1092 shm_add_rss_swap(shp, &rss, &swp);
1075 1093
1076#if BITS_PER_LONG <= 32 1094#if BITS_PER_LONG <= 32
1077#define SIZE_SPEC "%10lu" 1095#define SIZE_SPEC "%10lu"
@@ -1081,7 +1099,8 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
1081 1099
1082 return seq_printf(s, 1100 return seq_printf(s,
1083 "%10d %10d %4o " SIZE_SPEC " %5u %5u " 1101 "%10d %10d %4o " SIZE_SPEC " %5u %5u "
1084 "%5lu %5u %5u %5u %5u %10lu %10lu %10lu\n", 1102 "%5lu %5u %5u %5u %5u %10lu %10lu %10lu "
1103 SIZE_SPEC " " SIZE_SPEC "\n",
1085 shp->shm_perm.key, 1104 shp->shm_perm.key,
1086 shp->shm_perm.id, 1105 shp->shm_perm.id,
1087 shp->shm_perm.mode, 1106 shp->shm_perm.mode,
@@ -1095,6 +1114,8 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
1095 shp->shm_perm.cgid, 1114 shp->shm_perm.cgid,
1096 shp->shm_atim, 1115 shp->shm_atim,
1097 shp->shm_dtim, 1116 shp->shm_dtim,
1098 shp->shm_ctim); 1117 shp->shm_ctim,
1118 rss * PAGE_SIZE,
1119 swp * PAGE_SIZE);
1099} 1120}
1100#endif 1121#endif