Skip to content

Commit

Permalink
Merge branch 'akpm' (patches from Andrew)
Browse files Browse the repository at this point in the history
Merge fixes from Andrew Morton:
 "18 fixes"

[ The 18 fixes turned into 17 commits, because one of the fixes was a
  fix for another patch in the series that I just folded in by editing
  the patch manually - hopefully correctly     - Linus ]

* emailed patches from Andrew Morton <[email protected]>:
  mm: fix memory leak in copy_huge_pmd()
  drivers/hwspinlock: fix race between radix tree insertion and lookup
  radix-tree: fix race in gang lookup
  mm/vmpressure.c: fix subtree pressure detection
  mm: polish virtual memory accounting
  mm: warn about VmData over RLIMIT_DATA
  Documentation: cgroup-v2: add memory.stat::sock description
  mm: memcontrol: drop superfluous entry in the per-memcg stats array
  drivers/scsi/sg.c: mark VMA as VM_IO to prevent migration
  proc: revert /proc/<pid>/maps [stack:TID] annotation
  numa: fix /proc/<pid>/numa_maps for hugetlbfs on s390
  MAINTAINERS: update Seth email
  ocfs2/cluster: fix memory leak in o2hb_region_release
  lib/test-string_helpers.c: fix and improve string_get_size() tests
  thp: limit number of object to scan on deferred_split_scan()
  thp: change deferred_split_count() to return number of THP in queue
  thp: make split_queue per-node
  • Loading branch information
torvalds committed Feb 3, 2016
2 parents d5bfb96 + 12c9d70 commit b37a05c
Show file tree
Hide file tree
Showing 22 changed files with 269 additions and 193 deletions.
4 changes: 4 additions & 0 deletions Documentation/cgroup-v2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,10 @@ PAGE_SIZE multiple when read back.
Amount of memory used to cache filesystem data,
including tmpfs and shared memory.

sock

Amount of memory used in network transmission buffers

file_mapped

Amount of cached filesystem data mapped with mmap()
Expand Down
13 changes: 5 additions & 8 deletions Documentation/filesystems/proc.txt
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ Table 1-2: Contents of the status files (as of 4.1)
RssFile size of resident file mappings
RssShmem size of resident shmem memory (includes SysV shm,
mapping of tmpfs and shared anonymous mappings)
VmData size of data, stack, and text segments
VmStk size of data, stack, and text segments
VmData size of private data segments
VmStk size of stack segments
VmExe size of text segment
VmLib size of shared library code
VmPTE size of page table entries
Expand Down Expand Up @@ -356,7 +356,7 @@ address perms offset dev inode pathname
a7cb1000-a7cb2000 ---p 00000000 00:00 0
a7cb2000-a7eb2000 rw-p 00000000 00:00 0
a7eb2000-a7eb3000 ---p 00000000 00:00 0
a7eb3000-a7ed5000 rw-p 00000000 00:00 0 [stack:1001]
a7eb3000-a7ed5000 rw-p 00000000 00:00 0
a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6
a8008000-a800a000 r--p 00133000 03:00 4222 /lib/libc.so.6
a800a000-a800b000 rw-p 00135000 03:00 4222 /lib/libc.so.6
Expand Down Expand Up @@ -388,18 +388,15 @@ is not associated with a file:

[heap] = the heap of the program
[stack] = the stack of the main process
[stack:1001] = the stack of the thread with tid 1001
[vdso] = the "virtual dynamic shared object",
the kernel system call handler

or if empty, the mapping is anonymous.

The /proc/PID/task/TID/maps is a view of the virtual memory from the viewpoint
of the individual tasks of a process. In this file you will see a mapping marked
as [stack] if that task sees it as a stack. This is a key difference from the
content of /proc/PID/maps, where you will see all mappings that are being used
as stack by all of those tasks. Hence, for the example above, the task-level
map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this:
as [stack] if that task sees it as a stack. Hence, for the example above, the
task-level map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this:

08048000-08049000 r-xp 00000000 03:00 8312 /opt/test
08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test
Expand Down
5 changes: 5 additions & 0 deletions Documentation/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
could change it dynamically, usually by
/sys/module/printk/parameters/ignore_loglevel.

ignore_rlimit_data
Ignore RLIMIT_DATA setting for data mappings,
print warning at first misuse. Can be changed via
/sys/module/kernel/parameters/ignore_rlimit_data.

ihash_entries= [KNL]
Set number of hash buckets for inode cache.

Expand Down
4 changes: 2 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -12150,7 +12150,7 @@ F: drivers/net/hamradio/*scc.c
F: drivers/net/hamradio/z8530.h

ZBUD COMPRESSED PAGE ALLOCATOR
M: Seth Jennings <[email protected]>
M: Seth Jennings <[email protected]>
L: [email protected]
S: Maintained
F: mm/zbud.c
Expand Down Expand Up @@ -12205,7 +12205,7 @@ F: include/linux/zsmalloc.h
F: Documentation/vm/zsmalloc.txt

ZSWAP COMPRESSED SWAP CACHING
M: Seth Jennings <[email protected]>
M: Seth Jennings <[email protected]>
L: [email protected]
S: Maintained
F: mm/zswap.c
Expand Down
4 changes: 4 additions & 0 deletions drivers/hwspinlock/hwspinlock_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,10 @@ int of_hwspin_lock_get_id(struct device_node *np, int index)
hwlock = radix_tree_deref_slot(slot);
if (unlikely(!hwlock))
continue;
if (radix_tree_is_indirect_ptr(hwlock)) {
slot = radix_tree_iter_retry(&iter);
continue;
}

if (hwlock->bank->dev->of_node == args.np) {
ret = 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/sg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1261,7 +1261,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
}

sfp->mmap_called = 1;
vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops;
return 0;
Expand Down
14 changes: 8 additions & 6 deletions fs/ocfs2/cluster/heartbeat.c
Original file line number Diff line number Diff line change
Expand Up @@ -1254,15 +1254,15 @@ static const struct file_operations o2hb_debug_fops = {

void o2hb_exit(void)
{
kfree(o2hb_db_livenodes);
kfree(o2hb_db_liveregions);
kfree(o2hb_db_quorumregions);
kfree(o2hb_db_failedregions);
debugfs_remove(o2hb_debug_failedregions);
debugfs_remove(o2hb_debug_quorumregions);
debugfs_remove(o2hb_debug_liveregions);
debugfs_remove(o2hb_debug_livenodes);
debugfs_remove(o2hb_debug_dir);
kfree(o2hb_db_livenodes);
kfree(o2hb_db_liveregions);
kfree(o2hb_db_quorumregions);
kfree(o2hb_db_failedregions);
}

static struct dentry *o2hb_debug_create(const char *name, struct dentry *dir,
Expand Down Expand Up @@ -1438,13 +1438,15 @@ static void o2hb_region_release(struct config_item *item)

kfree(reg->hr_slots);

kfree(reg->hr_db_regnum);
kfree(reg->hr_db_livenodes);
debugfs_remove(reg->hr_debug_livenodes);
debugfs_remove(reg->hr_debug_regnum);
debugfs_remove(reg->hr_debug_elapsed_time);
debugfs_remove(reg->hr_debug_pinned);
debugfs_remove(reg->hr_debug_dir);
kfree(reg->hr_db_livenodes);
kfree(reg->hr_db_regnum);
kfree(reg->hr_debug_elapsed_time);
kfree(reg->hr_debug_pinned);

spin_lock(&o2hb_live_lock);
list_del(&reg->hr_all_item);
Expand Down
73 changes: 27 additions & 46 deletions fs/proc/task_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,23 +259,29 @@ static int do_maps_open(struct inode *inode, struct file *file,
sizeof(struct proc_maps_private));
}

static pid_t pid_of_stack(struct proc_maps_private *priv,
struct vm_area_struct *vma, bool is_pid)
/*
* Indicate if the VMA is a stack for the given task; for
* /proc/PID/maps that is the stack of the main task.
*/
static int is_stack(struct proc_maps_private *priv,
struct vm_area_struct *vma, int is_pid)
{
struct inode *inode = priv->inode;
struct task_struct *task;
pid_t ret = 0;
int stack = 0;

if (is_pid) {
stack = vma->vm_start <= vma->vm_mm->start_stack &&
vma->vm_end >= vma->vm_mm->start_stack;
} else {
struct inode *inode = priv->inode;
struct task_struct *task;

rcu_read_lock();
task = pid_task(proc_pid(inode), PIDTYPE_PID);
if (task) {
task = task_of_stack(task, vma, is_pid);
rcu_read_lock();
task = pid_task(proc_pid(inode), PIDTYPE_PID);
if (task)
ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info);
stack = vma_is_stack_for_task(vma, task);
rcu_read_unlock();
}
rcu_read_unlock();

return ret;
return stack;
}

static void
Expand Down Expand Up @@ -335,8 +341,6 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)

name = arch_vma_name(vma);
if (!name) {
pid_t tid;

if (!mm) {
name = "[vdso]";
goto done;
Expand All @@ -348,21 +352,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
goto done;
}

tid = pid_of_stack(priv, vma, is_pid);
if (tid != 0) {
/*
* Thread stack in /proc/PID/task/TID/maps or
* the main process stack.
*/
if (!is_pid || (vma->vm_start <= mm->start_stack &&
vma->vm_end >= mm->start_stack)) {
name = "[stack]";
} else {
/* Thread stack in /proc/PID/maps */
seq_pad(m, ' ');
seq_printf(m, "[stack:%d]", tid);
}
}
if (is_stack(priv, vma, is_pid))
name = "[stack]";
}

done:
Expand Down Expand Up @@ -1552,18 +1543,19 @@ static int gather_pte_stats(pmd_t *pmd, unsigned long addr,
static int gather_hugetlb_stats(pte_t *pte, unsigned long hmask,
unsigned long addr, unsigned long end, struct mm_walk *walk)
{
pte_t huge_pte = huge_ptep_get(pte);
struct numa_maps *md;
struct page *page;

if (!pte_present(*pte))
if (!pte_present(huge_pte))
return 0;

page = pte_page(*pte);
page = pte_page(huge_pte);
if (!page)
return 0;

md = walk->private;
gather_stats(page, md, pte_dirty(*pte), 1);
gather_stats(page, md, pte_dirty(huge_pte), 1);
return 0;
}

Expand Down Expand Up @@ -1617,19 +1609,8 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid)
seq_file_path(m, file, "\n\t= ");
} else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
seq_puts(m, " heap");
} else {
pid_t tid = pid_of_stack(proc_priv, vma, is_pid);
if (tid != 0) {
/*
* Thread stack in /proc/PID/task/TID/maps or
* the main process stack.
*/
if (!is_pid || (vma->vm_start <= mm->start_stack &&
vma->vm_end >= mm->start_stack))
seq_puts(m, " stack");
else
seq_printf(m, " stack:%d", tid);
}
} else if (is_stack(proc_priv, vma, is_pid)) {
seq_puts(m, " stack");
}

if (is_vm_hugetlb_page(vma))
Expand Down
49 changes: 20 additions & 29 deletions fs/proc/task_nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,23 +123,26 @@ unsigned long task_statm(struct mm_struct *mm,
return size;
}

static pid_t pid_of_stack(struct proc_maps_private *priv,
struct vm_area_struct *vma, bool is_pid)
static int is_stack(struct proc_maps_private *priv,
struct vm_area_struct *vma, int is_pid)
{
struct inode *inode = priv->inode;
struct task_struct *task;
pid_t ret = 0;

rcu_read_lock();
task = pid_task(proc_pid(inode), PIDTYPE_PID);
if (task) {
task = task_of_stack(task, vma, is_pid);
struct mm_struct *mm = vma->vm_mm;
int stack = 0;

if (is_pid) {
stack = vma->vm_start <= mm->start_stack &&
vma->vm_end >= mm->start_stack;
} else {
struct inode *inode = priv->inode;
struct task_struct *task;

rcu_read_lock();
task = pid_task(proc_pid(inode), PIDTYPE_PID);
if (task)
ret = task_pid_nr_ns(task, inode->i_sb->s_fs_info);
stack = vma_is_stack_for_task(vma, task);
rcu_read_unlock();
}
rcu_read_unlock();

return ret;
return stack;
}

/*
Expand Down Expand Up @@ -181,21 +184,9 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma,
if (file) {
seq_pad(m, ' ');
seq_file_path(m, file, "");
} else if (mm) {
pid_t tid = pid_of_stack(priv, vma, is_pid);

if (tid != 0) {
seq_pad(m, ' ');
/*
* Thread stack in /proc/PID/task/TID/maps or
* the main process stack.
*/
if (!is_pid || (vma->vm_start <= mm->start_stack &&
vma->vm_end >= mm->start_stack))
seq_printf(m, "[stack]");
else
seq_printf(m, "[stack:%d]", tid);
}
} else if (mm && is_stack(priv, vma, is_pid)) {
seq_pad(m, ' ');
seq_printf(m, "[stack]");
}

seq_putc(m, '\n');
Expand Down
2 changes: 1 addition & 1 deletion include/linux/memcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ enum mem_cgroup_stat_index {
MEM_CGROUP_STAT_SWAP, /* # of pages, swapped out */
MEM_CGROUP_STAT_NSTATS,
/* default hierarchy stats */
MEMCG_SOCK,
MEMCG_SOCK = MEM_CGROUP_STAT_NSTATS,
MEMCG_NR_STAT,
};

Expand Down
9 changes: 5 additions & 4 deletions include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,13 @@ extern unsigned int kobjsize(const void *objp);
#endif

#ifdef CONFIG_STACK_GROWSUP
#define VM_STACK_FLAGS (VM_GROWSUP | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
#define VM_STACK VM_GROWSUP
#else
#define VM_STACK_FLAGS (VM_GROWSDOWN | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)
#define VM_STACK VM_GROWSDOWN
#endif

#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT)

/*
* Special vmas that are non-mergable, non-mlock()able.
* Note: mm/huge_memory.c VM_NO_THP depends on this definition.
Expand Down Expand Up @@ -1341,8 +1343,7 @@ static inline int stack_guard_page_end(struct vm_area_struct *vma,
!vma_growsup(vma->vm_next, addr);
}

extern struct task_struct *task_of_stack(struct task_struct *task,
struct vm_area_struct *vma, bool in_group);
int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t);

extern unsigned long move_page_tables(struct vm_area_struct *vma,
unsigned long old_addr, struct vm_area_struct *new_vma,
Expand Down
6 changes: 3 additions & 3 deletions include/linux/mm_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,9 @@ struct mm_struct {
unsigned long total_vm; /* Total pages mapped */
unsigned long locked_vm; /* Pages that have PG_mlocked set */
unsigned long pinned_vm; /* Refcount permanently increased */
unsigned long data_vm; /* VM_WRITE & ~VM_SHARED/GROWSDOWN */
unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE */
unsigned long stack_vm; /* VM_GROWSUP/DOWN */
unsigned long data_vm; /* VM_WRITE & ~VM_SHARED & ~VM_STACK */
unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE & ~VM_STACK */
unsigned long stack_vm; /* VM_STACK */
unsigned long def_flags;
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
Expand Down
6 changes: 6 additions & 0 deletions include/linux/mmzone.h
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,12 @@ typedef struct pglist_data {
*/
unsigned long first_deferred_pfn;
#endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */

#ifdef CONFIG_TRANSPARENT_HUGEPAGE
spinlock_t split_queue_lock;
struct list_head split_queue;
unsigned long split_queue_len;
#endif
} pg_data_t;

#define node_present_pages(nid) (NODE_DATA(nid)->node_present_pages)
Expand Down
Loading

0 comments on commit b37a05c

Please sign in to comment.