mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 06:03:36 -04:00
Merge branch 'akpm' (patches from Andrew)
Merge updates from Andrew Morton:
- fsnotify updates
- ocfs2 updates
- all of MM
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (127 commits)
console: don't prefer first registered if DT specifies stdout-path
cred: simpler, 1D supplementary groups
CREDITS: update Pavel's information, add GPG key, remove snail mail address
mailmap: add Johan Hovold
.gitattributes: set git diff driver for C source code files
uprobes: remove function declarations from arch/{mips,s390}
spelling.txt: "modeled" is spelt correctly
nmi_backtrace: generate one-line reports for idle cpus
arch/tile: adopt the new nmi_backtrace framework
nmi_backtrace: do a local dump_stack() instead of a self-NMI
nmi_backtrace: add more trigger_*_cpu_backtrace() methods
min/max: remove sparse warnings when they're nested
Documentation/filesystems/proc.txt: add more description for maps/smaps
mm, proc: fix region lost in /proc/self/smaps
proc: fix timerslack_ns CAP_SYS_NICE check when adjusting self
proc: add LSM hook checks to /proc/<tid>/timerslack_ns
proc: relax /proc/<tid>/timerslack_ns capability requirements
meminfo: break apart a very long seq_printf with #ifdefs
seq/proc: modify seq_put_decimal_[u]ll to take a const char *, not char
proc: faster /proc/*/status
...
This commit is contained in:
commit
b66484cd74
195 changed files with 2522 additions and 1698 deletions
|
|
@ -511,7 +511,7 @@ static void exit_mm(struct task_struct *tsk)
|
|||
mm_update_next_owner(mm);
|
||||
mmput(mm);
|
||||
if (test_thread_flag(TIF_MEMDIE))
|
||||
exit_oom_victim(tsk);
|
||||
exit_oom_victim();
|
||||
}
|
||||
|
||||
static struct task_struct *find_alive_thread(struct task_struct *p)
|
||||
|
|
|
|||
|
|
@ -359,6 +359,12 @@ static inline void free_signal_struct(struct signal_struct *sig)
|
|||
{
|
||||
taskstats_tgid_free(sig);
|
||||
sched_autogroup_exit(sig);
|
||||
/*
|
||||
* __mmdrop is not safe to call from softirq context on x86 due to
|
||||
* pgd_dtor so postpone it to the async context
|
||||
*/
|
||||
if (sig->oom_mm)
|
||||
mmdrop_async(sig->oom_mm);
|
||||
kmem_cache_free(signal_cachep, sig);
|
||||
}
|
||||
|
||||
|
|
@ -848,6 +854,7 @@ static inline void __mmput(struct mm_struct *mm)
|
|||
ksm_exit(mm);
|
||||
khugepaged_exit(mm); /* must run before exit_mmap */
|
||||
exit_mmap(mm);
|
||||
mm_put_huge_zero_page(mm);
|
||||
set_mm_exe_file(mm, NULL);
|
||||
if (!list_empty(&mm->mmlist)) {
|
||||
spin_lock(&mmlist_lock);
|
||||
|
|
@ -856,6 +863,7 @@ static inline void __mmput(struct mm_struct *mm)
|
|||
}
|
||||
if (mm->binfmt)
|
||||
module_put(mm->binfmt->module);
|
||||
set_bit(MMF_OOM_SKIP, &mm->flags);
|
||||
mmdrop(mm);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,55 +7,31 @@
|
|||
#include <linux/security.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/user_namespace.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
struct group_info *groups_alloc(int gidsetsize)
|
||||
{
|
||||
struct group_info *group_info;
|
||||
int nblocks;
|
||||
int i;
|
||||
struct group_info *gi;
|
||||
unsigned int len;
|
||||
|
||||
nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;
|
||||
/* Make sure we always allocate at least one indirect block pointer */
|
||||
nblocks = nblocks ? : 1;
|
||||
group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER);
|
||||
if (!group_info)
|
||||
len = sizeof(struct group_info) + sizeof(kgid_t) * gidsetsize;
|
||||
gi = kmalloc(len, GFP_KERNEL_ACCOUNT|__GFP_NOWARN|__GFP_NORETRY);
|
||||
if (!gi)
|
||||
gi = __vmalloc(len, GFP_KERNEL_ACCOUNT|__GFP_HIGHMEM, PAGE_KERNEL);
|
||||
if (!gi)
|
||||
return NULL;
|
||||
group_info->ngroups = gidsetsize;
|
||||
group_info->nblocks = nblocks;
|
||||
atomic_set(&group_info->usage, 1);
|
||||
|
||||
if (gidsetsize <= NGROUPS_SMALL)
|
||||
group_info->blocks[0] = group_info->small_block;
|
||||
else {
|
||||
for (i = 0; i < nblocks; i++) {
|
||||
kgid_t *b;
|
||||
b = (void *)__get_free_page(GFP_USER);
|
||||
if (!b)
|
||||
goto out_undo_partial_alloc;
|
||||
group_info->blocks[i] = b;
|
||||
}
|
||||
}
|
||||
return group_info;
|
||||
|
||||
out_undo_partial_alloc:
|
||||
while (--i >= 0) {
|
||||
free_page((unsigned long)group_info->blocks[i]);
|
||||
}
|
||||
kfree(group_info);
|
||||
return NULL;
|
||||
atomic_set(&gi->usage, 1);
|
||||
gi->ngroups = gidsetsize;
|
||||
return gi;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(groups_alloc);
|
||||
|
||||
void groups_free(struct group_info *group_info)
|
||||
{
|
||||
if (group_info->blocks[0] != group_info->small_block) {
|
||||
int i;
|
||||
for (i = 0; i < group_info->nblocks; i++)
|
||||
free_page((unsigned long)group_info->blocks[i]);
|
||||
}
|
||||
kfree(group_info);
|
||||
kvfree(group_info);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(groups_free);
|
||||
|
|
@ -70,7 +46,7 @@ static int groups_to_user(gid_t __user *grouplist,
|
|||
|
||||
for (i = 0; i < count; i++) {
|
||||
gid_t gid;
|
||||
gid = from_kgid_munged(user_ns, GROUP_AT(group_info, i));
|
||||
gid = from_kgid_munged(user_ns, group_info->gid[i]);
|
||||
if (put_user(gid, grouplist+i))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
|
@ -95,7 +71,7 @@ static int groups_from_user(struct group_info *group_info,
|
|||
if (!gid_valid(kgid))
|
||||
return -EINVAL;
|
||||
|
||||
GROUP_AT(group_info, i) = kgid;
|
||||
group_info->gid[i] = kgid;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -115,15 +91,14 @@ static void groups_sort(struct group_info *group_info)
|
|||
for (base = 0; base < max; base++) {
|
||||
int left = base;
|
||||
int right = left + stride;
|
||||
kgid_t tmp = GROUP_AT(group_info, right);
|
||||
kgid_t tmp = group_info->gid[right];
|
||||
|
||||
while (left >= 0 && gid_gt(GROUP_AT(group_info, left), tmp)) {
|
||||
GROUP_AT(group_info, right) =
|
||||
GROUP_AT(group_info, left);
|
||||
while (left >= 0 && gid_gt(group_info->gid[left], tmp)) {
|
||||
group_info->gid[right] = group_info->gid[left];
|
||||
right = left;
|
||||
left -= stride;
|
||||
}
|
||||
GROUP_AT(group_info, right) = tmp;
|
||||
group_info->gid[right] = tmp;
|
||||
}
|
||||
stride /= 3;
|
||||
}
|
||||
|
|
@ -141,9 +116,9 @@ int groups_search(const struct group_info *group_info, kgid_t grp)
|
|||
right = group_info->ngroups;
|
||||
while (left < right) {
|
||||
unsigned int mid = (left+right)/2;
|
||||
if (gid_gt(grp, GROUP_AT(group_info, mid)))
|
||||
if (gid_gt(grp, group_info->gid[mid]))
|
||||
left = mid + 1;
|
||||
else if (gid_lt(grp, GROUP_AT(group_info, mid)))
|
||||
else if (gid_lt(grp, group_info->gid[mid]))
|
||||
right = mid;
|
||||
else
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -144,23 +144,12 @@ int freeze_processes(void)
|
|||
/*
|
||||
* Now that the whole userspace is frozen we need to disbale
|
||||
* the OOM killer to disallow any further interference with
|
||||
* killable tasks.
|
||||
* killable tasks. There is no guarantee oom victims will
|
||||
* ever reach a point they go away we have to wait with a timeout.
|
||||
*/
|
||||
if (!error && !oom_killer_disable())
|
||||
if (!error && !oom_killer_disable(msecs_to_jiffies(freeze_timeout_msecs)))
|
||||
error = -EBUSY;
|
||||
|
||||
/*
|
||||
* There is a hard to fix race between oom_reaper kernel thread
|
||||
* and oom_killer_disable. oom_reaper calls exit_oom_victim
|
||||
* before the victim reaches exit_mm so try to freeze all the tasks
|
||||
* again and catch such a left over task.
|
||||
*/
|
||||
if (!error) {
|
||||
pr_info("Double checking all user space processes after OOM killer disable... ");
|
||||
error = try_to_freeze_tasks(true);
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
if (error)
|
||||
thaw_processes();
|
||||
return error;
|
||||
|
|
|
|||
|
|
@ -253,6 +253,17 @@ static int preferred_console = -1;
|
|||
int console_set_on_cmdline;
|
||||
EXPORT_SYMBOL(console_set_on_cmdline);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static bool of_specified_console;
|
||||
|
||||
void console_set_by_of(void)
|
||||
{
|
||||
of_specified_console = true;
|
||||
}
|
||||
#else
|
||||
# define of_specified_console false
|
||||
#endif
|
||||
|
||||
/* Flag: console code may call schedule() */
|
||||
static int console_may_schedule;
|
||||
|
||||
|
|
@ -2647,7 +2658,7 @@ void register_console(struct console *newcon)
|
|||
* didn't select a console we take the first one
|
||||
* that registers here.
|
||||
*/
|
||||
if (preferred_console < 0) {
|
||||
if (preferred_console < 0 && !of_specified_console) {
|
||||
if (newcon->index < 0)
|
||||
newcon->index = 0;
|
||||
if (newcon->setup == NULL ||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
#include "sched.h"
|
||||
|
||||
/* Linker adds these: start and end of __cpuidle functions */
|
||||
extern char __cpuidle_text_start[], __cpuidle_text_end[];
|
||||
|
||||
/**
|
||||
* sched_idle_set_state - Record idle state for the current CPU.
|
||||
* @idle_state: State to record.
|
||||
|
|
@ -53,7 +56,7 @@ static int __init cpu_idle_nopoll_setup(char *__unused)
|
|||
__setup("hlt", cpu_idle_nopoll_setup);
|
||||
#endif
|
||||
|
||||
static inline int cpu_idle_poll(void)
|
||||
static noinline int __cpuidle cpu_idle_poll(void)
|
||||
{
|
||||
rcu_idle_enter();
|
||||
trace_cpu_idle_rcuidle(0, smp_processor_id());
|
||||
|
|
@ -84,7 +87,7 @@ void __weak arch_cpu_idle(void)
|
|||
*
|
||||
* To use when the cpuidle framework cannot be used.
|
||||
*/
|
||||
void default_idle_call(void)
|
||||
void __cpuidle default_idle_call(void)
|
||||
{
|
||||
if (current_clr_polling_and_test()) {
|
||||
local_irq_enable();
|
||||
|
|
@ -271,6 +274,12 @@ static void cpu_idle_loop(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool cpu_in_idle(unsigned long pc)
|
||||
{
|
||||
return pc >= (unsigned long)__cpuidle_text_start &&
|
||||
pc < (unsigned long)__cpuidle_text_end;
|
||||
}
|
||||
|
||||
void cpu_startup_entry(enum cpuhp_state state)
|
||||
{
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ static int groups16_to_user(old_gid_t __user *grouplist,
|
|||
kgid_t kgid;
|
||||
|
||||
for (i = 0; i < group_info->ngroups; i++) {
|
||||
kgid = GROUP_AT(group_info, i);
|
||||
kgid = group_info->gid[i];
|
||||
group = high2lowgid(from_kgid_munged(user_ns, kgid));
|
||||
if (put_user(group, grouplist+i))
|
||||
return -EFAULT;
|
||||
|
|
@ -142,7 +142,7 @@ static int groups16_from_user(struct group_info *group_info,
|
|||
if (!gid_valid(kgid))
|
||||
return -EINVAL;
|
||||
|
||||
GROUP_AT(group_info, i) = kgid;
|
||||
group_info->gid[i] = kgid;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue