On Sun, 19 Jul 2015 15:31:13 +0300 Vladimir Davydov <vdavydov@xxxxxxxxxxxxx> wrote: > /proc/kpagecgroup contains a 64-bit inode number of the memory cgroup > each page is charged to, indexed by PFN. Having this information is > useful for estimating a cgroup working set size. > > The file is present if CONFIG_PROC_PAGE_MONITOR && CONFIG_MEMCG. > > ... > > @@ -225,10 +226,62 @@ static const struct file_operations proc_kpageflags_operations = { > .read = kpageflags_read, > }; > > +#ifdef CONFIG_MEMCG > +static ssize_t kpagecgroup_read(struct file *file, char __user *buf, > + size_t count, loff_t *ppos) > +{ > + u64 __user *out = (u64 __user *)buf; > + struct page *ppage; > + unsigned long src = *ppos; > + unsigned long pfn; > + ssize_t ret = 0; > + u64 ino; > + > + pfn = src / KPMSIZE; > + count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); > + if (src & KPMMASK || count & KPMMASK) > + return -EINVAL; The user-facing documentation should explain that reads must be performed in multiple-of-8 sizes. > + while (count > 0) { > + if (pfn_valid(pfn)) > + ppage = pfn_to_page(pfn); > + else > + ppage = NULL; > + > + if (ppage) > + ino = page_cgroup_ino(ppage); > + else > + ino = 0; > + > + if (put_user(ino, out)) { > + ret = -EFAULT; Here we do the usual procfs violation of read() behaviour. read() normally only returns an error if it read nothing. This code will transfer a megabyte then return -EFAULT so userspace doesn't know that it got that megabyte. That's easy to fix, but procfs files do this all over the place anyway :( > + break; > + } > + > + pfn++; > + out++; > + count -= KPMSIZE; > + } > + > + *ppos += (char __user *)out - buf; > + if (!ret) > + ret = (char __user *)out - buf; > + return ret; > +} > + -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>