aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/compat.c6
-rw-r--r--ipc/compat_mq.c5
-rw-r--r--ipc/shm.c63
3 files changed, 53 insertions, 21 deletions
diff --git a/ipc/compat.c b/ipc/compat.c
index 9dc2c7d3c9e6..845a28738d3a 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -241,6 +241,8 @@ long compat_sys_semctl(int first, int second, int third, void __user *uptr)
241 struct semid64_ds __user *up64; 241 struct semid64_ds __user *up64;
242 int version = compat_ipc_parse_version(&third); 242 int version = compat_ipc_parse_version(&third);
243 243
244 memset(&s64, 0, sizeof(s64));
245
244 if (!uptr) 246 if (!uptr)
245 return -EINVAL; 247 return -EINVAL;
246 if (get_user(pad, (u32 __user *) uptr)) 248 if (get_user(pad, (u32 __user *) uptr))
@@ -421,6 +423,8 @@ long compat_sys_msgctl(int first, int second, void __user *uptr)
421 int version = compat_ipc_parse_version(&second); 423 int version = compat_ipc_parse_version(&second);
422 void __user *p; 424 void __user *p;
423 425
426 memset(&m64, 0, sizeof(m64));
427
424 switch (second & (~IPC_64)) { 428 switch (second & (~IPC_64)) {
425 case IPC_INFO: 429 case IPC_INFO:
426 case IPC_RMID: 430 case IPC_RMID:
@@ -594,6 +598,8 @@ long compat_sys_shmctl(int first, int second, void __user *uptr)
594 int err, err2; 598 int err, err2;
595 int version = compat_ipc_parse_version(&second); 599 int version = compat_ipc_parse_version(&second);
596 600
601 memset(&s64, 0, sizeof(s64));
602
597 switch (second & (~IPC_64)) { 603 switch (second & (~IPC_64)) {
598 case IPC_RMID: 604 case IPC_RMID:
599 case SHM_LOCK: 605 case SHM_LOCK:
diff --git a/ipc/compat_mq.c b/ipc/compat_mq.c
index d8d1e9ff4e88..380ea4fe08e7 100644
--- a/ipc/compat_mq.c
+++ b/ipc/compat_mq.c
@@ -53,6 +53,9 @@ asmlinkage long compat_sys_mq_open(const char __user *u_name,
53 void __user *p = NULL; 53 void __user *p = NULL;
54 if (u_attr && oflag & O_CREAT) { 54 if (u_attr && oflag & O_CREAT) {
55 struct mq_attr attr; 55 struct mq_attr attr;
56
57 memset(&attr, 0, sizeof(attr));
58
56 p = compat_alloc_user_space(sizeof(attr)); 59 p = compat_alloc_user_space(sizeof(attr));
57 if (get_compat_mq_attr(&attr, u_attr) || 60 if (get_compat_mq_attr(&attr, u_attr) ||
58 copy_to_user(p, &attr, sizeof(attr))) 61 copy_to_user(p, &attr, sizeof(attr)))
@@ -127,6 +130,8 @@ asmlinkage long compat_sys_mq_getsetattr(mqd_t mqdes,
127 struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p)); 130 struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p));
128 long ret; 131 long ret;
129 132
133 memset(&mqstat, 0, sizeof(mqstat));
134
130 if (u_mqstat) { 135 if (u_mqstat) {
131 if (get_compat_mq_attr(&mqstat, u_mqstat) || 136 if (get_compat_mq_attr(&mqstat, u_mqstat) ||
132 copy_to_user(p, &mqstat, sizeof(mqstat))) 137 copy_to_user(p, &mqstat, sizeof(mqstat)))
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