Merge branch 'linaro-android-3.10-lsk' of git://android.git.linaro.org/kernel/linaro-android into lsk-v3.10-aosp

This commit is contained in:
Mark Brown 2014-11-12 21:29:20 +00:00
commit fea95ac027
24 changed files with 263 additions and 63 deletions

View File

@ -1333,6 +1333,19 @@ ndisc_notify - BOOLEAN
1 - Generate unsolicited neighbour advertisements when device is brought
up or hardware address changes.
optimistic_dad - BOOLEAN
Whether to perform Optimistic Duplicate Address Detection (RFC 4429).
0: disabled (default)
1: enabled
use_optimistic - BOOLEAN
If enabled, do not classify optimistic addresses as deprecated during
source address selection. Preferred addresses will still be chosen
before optimistic addresses, subject to other ranking in the source
address selection algorithm.
0: disabled (default)
1: enabled
icmp/*:
ratelimit - INTEGER
Limit the maximal rates for sending ICMPv6 packets.

View File

@ -15,7 +15,7 @@
#include <uapi/asm/unistd.h>
#define __NR_syscalls (380)
#define __NR_syscalls (384)
#define __ARM_NR_cmpxchg (__ARM_NR_BASE+0x00fff0)
#define __ARCH_WANT_STAT64

View File

@ -406,6 +406,12 @@
#define __NR_process_vm_writev (__NR_SYSCALL_BASE+377)
#define __NR_kcmp (__NR_SYSCALL_BASE+378)
#define __NR_finit_module (__NR_SYSCALL_BASE+379)
/* Reserve for later
#define __NR_sched_setattr (__NR_SYSCALL_BASE+380)
#define __NR_sched_getattr (__NR_SYSCALL_BASE+381)
#define __NR_renameat2 (__NR_SYSCALL_BASE+382)
*/
#define __NR_seccomp (__NR_SYSCALL_BASE+383)
/*
* This may need to be greater than __NR_last_syscall+1 in order to

View File

@ -389,6 +389,11 @@
CALL(sys_process_vm_writev)
CALL(sys_kcmp)
CALL(sys_finit_module)
/* 380 */ CALL(sys_ni_syscall) /* reserved sys_sched_setattr */
CALL(sys_ni_syscall) /* reserved sys_sched_getattr */
CALL(sys_ni_syscall) /* reserved sys_renameat2 */
CALL(sys_seccomp)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted

View File

@ -916,7 +916,7 @@ enum ptrace_syscall_dir {
PTRACE_SYSCALL_EXIT,
};
static int tracehook_report_syscall(struct pt_regs *regs,
static void tracehook_report_syscall(struct pt_regs *regs,
enum ptrace_syscall_dir dir)
{
unsigned long ip;
@ -934,7 +934,6 @@ static int tracehook_report_syscall(struct pt_regs *regs,
current_thread_info()->syscall = -1;
regs->ARM_ip = ip;
return current_thread_info()->syscall;
}
asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
@ -946,7 +945,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
return -1;
if (test_thread_flag(TIF_SYSCALL_TRACE))
scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
scno = current_thread_info()->syscall;
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, scno);

View File

@ -30,6 +30,7 @@
#include <linux/suspend.h>
#include <linux/cpuidle.h>
#include <linux/timer.h>
#include <linux/wakeup_reason.h>
#include "../base.h"
#include "power.h"
@ -938,6 +939,7 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state)
static int dpm_suspend_noirq(pm_message_t state)
{
ktime_t starttime = ktime_get();
char suspend_abort[MAX_SUSPEND_ABORT_LEN];
int error = 0;
cpuidle_pause();
@ -965,6 +967,9 @@ static int dpm_suspend_noirq(pm_message_t state)
put_device(dev);
if (pm_wakeup_pending()) {
pm_get_active_wakeup_sources(suspend_abort,
MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
error = -EBUSY;
break;
}
@ -1023,6 +1028,7 @@ static int device_suspend_late(struct device *dev, pm_message_t state)
static int dpm_suspend_late(pm_message_t state)
{
ktime_t starttime = ktime_get();
char suspend_abort[MAX_SUSPEND_ABORT_LEN];
int error = 0;
mutex_lock(&dpm_list_mtx);
@ -1048,6 +1054,9 @@ static int dpm_suspend_late(pm_message_t state)
put_device(dev);
if (pm_wakeup_pending()) {
pm_get_active_wakeup_sources(suspend_abort,
MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
error = -EBUSY;
break;
}
@ -1115,6 +1124,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
char *info = NULL;
int error = 0;
struct dpm_watchdog wd;
char suspend_abort[MAX_SUSPEND_ABORT_LEN];
dpm_wait_for_children(dev, async);
@ -1131,6 +1141,9 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async)
pm_wakeup_event(dev, 0);
if (pm_wakeup_pending()) {
pm_get_active_wakeup_sources(suspend_abort,
MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
async_error = -EBUSY;
goto Complete;
}

View File

@ -659,6 +659,22 @@ void pm_wakeup_event(struct device *dev, unsigned int msec)
}
EXPORT_SYMBOL_GPL(pm_wakeup_event);
void pm_get_active_wakeup_sources(char *pending_wakeup_source, size_t max)
{
struct wakeup_source *ws;
int len = 0;
rcu_read_lock();
len += snprintf(pending_wakeup_source, max, "Pending Wakeup Sources: ");
list_for_each_entry_rcu(ws, &wakeup_sources, entry) {
if (ws->active) {
len += snprintf(pending_wakeup_source + len, max,
"%s ", ws->name);
}
}
rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(pm_get_active_wakeup_sources);
static void print_active_wakeup_sources(void)
{
struct wakeup_source *ws;

View File

@ -10,6 +10,7 @@
#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/wakeup_reason.h>
static LIST_HEAD(syscore_ops_list);
static DEFINE_MUTEX(syscore_ops_lock);
@ -73,6 +74,8 @@ int syscore_suspend(void)
return 0;
err_out:
log_suspend_abort_reason("System core suspend callback %pF failed",
ops->suspend);
pr_err("PM: System core suspend callback %pF failed.\n", ops->suspend);
list_for_each_entry_continue(ops, &syscore_ops_list, node)

View File

@ -282,19 +282,19 @@ static void cpufreq_stats_free_sysfs(unsigned int cpu)
static void cpufreq_allstats_free(void)
{
int i;
int cpu;
struct all_cpufreq_stats *all_stat;
sysfs_remove_file(cpufreq_global_kobject,
&_attr_all_time_in_state.attr);
for (i = 0; i < total_cpus; i++) {
all_stat = per_cpu(all_cpufreq_stats, i);
for_each_possible_cpu(cpu) {
all_stat = per_cpu(all_cpufreq_stats, cpu);
if (!all_stat)
continue;
kfree(all_stat->time_in_state);
kfree(all_stat);
per_cpu(all_cpufreq_stats, i) = NULL;
per_cpu(all_cpufreq_stats, cpu) = NULL;
}
if (all_freq_table) {
kfree(all_freq_table->freq_table);

View File

@ -831,6 +831,17 @@ unsigned short css_id(struct cgroup_subsys_state *css);
unsigned short css_depth(struct cgroup_subsys_state *css);
struct cgroup_subsys_state *cgroup_css_from_dir(struct file *f, int id);
/*
* Default Android check for whether the current process is allowed to move a
* task across cgroups, either because CAP_SYS_NICE is set or because the uid
* of the calling process is the same as the moved task or because we are
* running as root.
* Returns 0 if this is allowed, or -EACCES otherwise.
*/
int subsys_cgroup_allow_attach(struct cgroup *cgrp,
struct cgroup_taskset *tset);
#else /* !CONFIG_CGROUPS */
static inline int cgroup_init_early(void) { return 0; }
@ -854,6 +865,11 @@ static inline int cgroup_attach_task_all(struct task_struct *from,
return 0;
}
static inline int subsys_cgroup_allow_attach(struct cgroup *cgrp,
struct cgroup_taskset *tset)
{
return 0;
}
#endif /* !CONFIG_CGROUPS */
#endif /* _LINUX_CGROUP_H */

View File

@ -41,6 +41,7 @@ struct ipv6_devconf {
__s32 accept_source_route;
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
__s32 optimistic_dad;
__s32 use_optimistic;
#endif
#ifdef CONFIG_IPV6_MROUTE
__s32 mc_forwarding;

View File

@ -363,7 +363,7 @@ extern bool pm_wakeup_pending(void);
extern bool pm_get_wakeup_count(unsigned int *count, bool block);
extern bool pm_save_wakeup_count(unsigned int count);
extern void pm_wakep_autosleep_enabled(bool set);
extern void pm_get_active_wakeup_sources(char *pending_sources, size_t max);
static inline void lock_system_sleep(void)
{
current->flags |= PF_FREEZER_SKIP;

View File

@ -18,6 +18,10 @@
#ifndef _LINUX_WAKEUP_REASON_H
#define _LINUX_WAKEUP_REASON_H
#define MAX_SUSPEND_ABORT_LEN 256
void log_wakeup_reason(int irq);
void log_suspend_abort_reason(const char *fmt, ...);
int check_wakeup_reason(int irq);
#endif /* _LINUX_WAKEUP_REASON_H */

View File

@ -161,6 +161,7 @@ enum {
DEVCONF_FORCE_TLLAO,
DEVCONF_NDISC_NOTIFY,
DEVCONF_ACCEPT_RA_RT_TABLE,
DEVCONF_USE_OPTIMISTIC,
DEVCONF_MAX
};

View File

@ -57,6 +57,7 @@
#define MAX_NUM_CODECS 32
#define MAX_NUM_CODEC_DESCRIPTORS 32
#define MAX_NUM_BITRATES 32
#define MAX_NUM_SAMPLE_RATES 32
/* Codecs are listed linearly to allow for extensibility */
#define SND_AUDIOCODEC_PCM ((__u32) 0x00000001)
@ -324,7 +325,8 @@ union snd_codec_options {
/** struct snd_codec_desc - description of codec capabilities
* @max_ch: Maximum number of audio channels
* @sample_rates: Sampling rates in Hz, use SNDRV_PCM_RATE_xxx for this
* @sample_rates: Sampling rates in Hz, use values like 48000 for this
* @num_sample_rates: Number of valid values in sample_rates array
* @bit_rate: Indexed array containing supported bit rates
* @num_bitrates: Number of valid values in bit_rate array
* @rate_control: value is specified by SND_RATECONTROLMODE defines.
@ -346,7 +348,8 @@ union snd_codec_options {
struct snd_codec_desc {
__u32 max_ch;
__u32 sample_rates;
__u32 sample_rates[MAX_NUM_SAMPLE_RATES];
__u32 num_sample_rates;
__u32 bit_rate[MAX_NUM_BITRATES];
__u32 num_bitrates;
__u32 rate_control;
@ -364,7 +367,8 @@ struct snd_codec_desc {
* @ch_out: Number of output channels. In case of contradiction between
* this field and the channelMode field, the channelMode field
* overrides.
* @sample_rate: Audio sample rate of input data
* @sample_rate: Audio sample rate of input data in Hz, use values like 48000
* for this.
* @bit_rate: Bitrate of encoded data. May be ignored by decoders
* @rate_control: Encoding rate control. See SND_RATECONTROLMODE defines.
* Encoders may rely on profiles for quality levels.

View File

@ -2116,6 +2116,25 @@ static int cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
return 0;
}
int subsys_cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
{
const struct cred *cred = current_cred(), *tcred;
struct task_struct *task;
if (capable(CAP_SYS_NICE))
return 0;
cgroup_taskset_for_each(task, cgrp, tset) {
tcred = __task_cred(task);
if (current != task && cred->euid != tcred->uid &&
cred->euid != tcred->suid)
return -EACCES;
}
return 0;
}
/*
* Find the task_struct of the task to attach by vpid and pass it along to the
* function to attach either it or all tasks in its threadgroup. Will lock

View File

@ -10,7 +10,7 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/syscore_ops.h>
#include <linux/wakeup_reason.h>
#include "internals.h"
/**
@ -100,11 +100,16 @@ EXPORT_SYMBOL_GPL(resume_device_irqs);
int check_wakeup_irqs(void)
{
struct irq_desc *desc;
char suspend_abort[MAX_SUSPEND_ABORT_LEN];
int irq;
for_each_irq_desc(irq, desc) {
if (irqd_is_wakeup_set(&desc->irq_data)) {
if (desc->istate & IRQS_PENDING) {
log_suspend_abort_reason("Wakeup IRQ %d %s pending",
irq,
desc->action && desc->action->name ?
desc->action->name : "");
pr_info("Wakeup IRQ %d %s pending, suspend aborted\n",
irq,
desc->action && desc->action->name ?

View File

@ -17,7 +17,7 @@
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/kmod.h>
#include <linux/wakeup_reason.h>
/*
* Timeout for stopping processes
*/
@ -34,6 +34,7 @@ static int try_to_freeze_tasks(bool user_only)
unsigned int elapsed_msecs;
bool wakeup = false;
int sleep_usecs = USEC_PER_MSEC;
char suspend_abort[MAX_SUSPEND_ABORT_LEN];
do_gettimeofday(&start);
@ -63,6 +64,9 @@ static int try_to_freeze_tasks(bool user_only)
break;
if (pm_wakeup_pending()) {
pm_get_active_wakeup_sources(suspend_abort,
MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
wakeup = true;
break;
}
@ -82,23 +86,24 @@ static int try_to_freeze_tasks(bool user_only)
do_div(elapsed_msecs64, NSEC_PER_MSEC);
elapsed_msecs = elapsed_msecs64;
if (todo) {
if (wakeup) {
printk("\n");
printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds "
"(%d tasks refusing to freeze, wq_busy=%d):\n",
wakeup ? "aborted" : "failed",
printk(KERN_ERR "Freezing of tasks aborted after %d.%03d seconds",
elapsed_msecs / 1000, elapsed_msecs % 1000);
} else if (todo) {
printk("\n");
printk(KERN_ERR "Freezing of tasks failed after %d.%03d seconds"
" (%d tasks refusing to freeze, wq_busy=%d):\n",
elapsed_msecs / 1000, elapsed_msecs % 1000,
todo - wq_busy, wq_busy);
if (!wakeup) {
read_lock(&tasklist_lock);
do_each_thread(g, p) {
if (p != current && !freezer_should_skip(p)
&& freezing(p) && !frozen(p))
sched_show_task(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
}
read_lock(&tasklist_lock);
do_each_thread(g, p) {
if (p != current && !freezer_should_skip(p)
&& freezing(p) && !frozen(p))
sched_show_task(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
} else {
printk("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
elapsed_msecs % 1000);

View File

@ -27,6 +27,7 @@
#include <linux/ftrace.h>
#include <linux/rtc.h>
#include <trace/events/power.h>
#include <linux/wakeup_reason.h>
#include "power.h"
@ -147,7 +148,7 @@ static int suspend_prepare(suspend_state_t state)
error = suspend_freeze_processes();
if (!error)
return 0;
log_suspend_abort_reason("One or more tasks refusing to freeze");
suspend_stats.failed_freeze++;
dpm_save_failed_step(SUSPEND_FREEZE);
Finish:
@ -177,7 +178,8 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void)
*/
static int suspend_enter(suspend_state_t state, bool *wakeup)
{
int error;
char suspend_abort[MAX_SUSPEND_ABORT_LEN];
int error, last_dev;
if (need_suspend_ops(state) && suspend_ops->prepare) {
error = suspend_ops->prepare();
@ -187,7 +189,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
error = dpm_suspend_end(PMSG_SUSPEND);
if (error) {
last_dev = suspend_stats.last_failed_dev + REC_FAILED_NUM - 1;
last_dev %= REC_FAILED_NUM;
printk(KERN_ERR "PM: Some devices failed to power down\n");
log_suspend_abort_reason("%s device failed to power down",
suspend_stats.failed_devs[last_dev]);
goto Platform_finish;
}
@ -212,8 +218,10 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
}
error = disable_nonboot_cpus();
if (error || suspend_test(TEST_CPUS))
if (error || suspend_test(TEST_CPUS)) {
log_suspend_abort_reason("Disabling non-boot cpus failed");
goto Enable_cpus;
}
arch_suspend_disable_irqs();
BUG_ON(!irqs_disabled());
@ -224,6 +232,10 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
if (!(suspend_test(TEST_CORE) || *wakeup)) {
error = suspend_ops->enter(state);
events_check_enabled = false;
} else {
pm_get_active_wakeup_sources(suspend_abort,
MAX_SUSPEND_ABORT_LEN);
log_suspend_abort_reason(suspend_abort);
}
syscore_resume();
}
@ -271,6 +283,7 @@ int suspend_devices_and_enter(suspend_state_t state)
error = dpm_suspend_start(PMSG_SUSPEND);
if (error) {
printk(KERN_ERR "PM: Some devices failed to suspend\n");
log_suspend_abort_reason("Some devices failed to suspend");
goto Recover_platform;
}
suspend_test_finish("suspend devices");

View File

@ -31,8 +31,10 @@
#define MAX_WAKEUP_REASON_IRQS 32
static int irq_list[MAX_WAKEUP_REASON_IRQS];
static int irqcount;
static bool suspend_abort;
static char abort_reason[MAX_SUSPEND_ABORT_LEN];
static struct kobject *wakeup_reason;
static spinlock_t resume_reason_lock;
static DEFINE_SPINLOCK(resume_reason_lock);
static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
@ -40,14 +42,18 @@ static ssize_t last_resume_reason_show(struct kobject *kobj, struct kobj_attribu
int irq_no, buf_offset = 0;
struct irq_desc *desc;
spin_lock(&resume_reason_lock);
for (irq_no = 0; irq_no < irqcount; irq_no++) {
desc = irq_to_desc(irq_list[irq_no]);
if (desc && desc->action && desc->action->name)
buf_offset += sprintf(buf + buf_offset, "%d %s\n",
irq_list[irq_no], desc->action->name);
else
buf_offset += sprintf(buf + buf_offset, "%d\n",
irq_list[irq_no]);
if (suspend_abort) {
buf_offset = sprintf(buf, "Abort: %s", abort_reason);
} else {
for (irq_no = 0; irq_no < irqcount; irq_no++) {
desc = irq_to_desc(irq_list[irq_no]);
if (desc && desc->action && desc->action->name)
buf_offset += sprintf(buf + buf_offset, "%d %s\n",
irq_list[irq_no], desc->action->name);
else
buf_offset += sprintf(buf + buf_offset, "%d\n",
irq_list[irq_no]);
}
}
spin_unlock(&resume_reason_lock);
return buf_offset;
@ -89,6 +95,40 @@ void log_wakeup_reason(int irq)
spin_unlock(&resume_reason_lock);
}
int check_wakeup_reason(int irq)
{
int irq_no;
int ret = false;
spin_lock(&resume_reason_lock);
for (irq_no = 0; irq_no < irqcount; irq_no++)
if (irq_list[irq_no] == irq) {
ret = true;
break;
}
spin_unlock(&resume_reason_lock);
return ret;
}
void log_suspend_abort_reason(const char *fmt, ...)
{
va_list args;
spin_lock(&resume_reason_lock);
//Suspend abort reason has already been logged.
if (suspend_abort) {
spin_unlock(&resume_reason_lock);
return;
}
suspend_abort = true;
va_start(args, fmt);
snprintf(abort_reason, MAX_SUSPEND_ABORT_LEN, fmt, args);
va_end(args);
spin_unlock(&resume_reason_lock);
}
/* Detects a suspend and clears all the previous wake up reasons*/
static int wakeup_reason_pm_event(struct notifier_block *notifier,
unsigned long pm_event, void *unused)
@ -97,6 +137,7 @@ static int wakeup_reason_pm_event(struct notifier_block *notifier,
case PM_SUSPEND_PREPARE:
spin_lock(&resume_reason_lock);
irqcount = 0;
suspend_abort = false;
spin_unlock(&resume_reason_lock);
break;
default:
@ -115,7 +156,7 @@ static struct notifier_block wakeup_reason_pm_notifier_block = {
int __init wakeup_reason_init(void)
{
int retval;
spin_lock_init(&resume_reason_lock);
retval = register_pm_notifier(&wakeup_reason_pm_notifier_block);
if (retval)
printk(KERN_WARNING "[%s] failed to register PM notifier %d\n",

View File

@ -7716,23 +7716,6 @@ static void cpu_cgroup_css_offline(struct cgroup *cgrp)
sched_offline_group(tg);
}
static int
cpu_cgroup_allow_attach(struct cgroup *cgrp, struct cgroup_taskset *tset)
{
const struct cred *cred = current_cred(), *tcred;
struct task_struct *task;
cgroup_taskset_for_each(task, cgrp, tset) {
tcred = __task_cred(task);
if ((current != task) && !capable(CAP_SYS_NICE) &&
cred->euid != tcred->uid && cred->euid != tcred->suid)
return -EACCES;
}
return 0;
}
static int cpu_cgroup_can_attach(struct cgroup *cgrp,
struct cgroup_taskset *tset)
{
@ -8092,7 +8075,7 @@ struct cgroup_subsys cpu_cgroup_subsys = {
.css_offline = cpu_cgroup_css_offline,
.can_attach = cpu_cgroup_can_attach,
.attach = cpu_cgroup_attach,
.allow_attach = cpu_cgroup_allow_attach,
.allow_attach = subsys_cgroup_allow_attach,
.exit = cpu_cgroup_exit,
.subsys_id = cpu_cgroup_subsys_id,
.base_cftypes = cpu_files,

View File

@ -6753,6 +6753,12 @@ static int mem_cgroup_can_attach(struct cgroup *cgroup,
return ret;
}
static int mem_cgroup_allow_attach(struct cgroup *cgroup,
struct cgroup_taskset *tset)
{
return subsys_cgroup_allow_attach(cgroup, tset);
}
static void mem_cgroup_cancel_attach(struct cgroup *cgroup,
struct cgroup_taskset *tset)
{
@ -6921,6 +6927,11 @@ static int mem_cgroup_can_attach(struct cgroup *cgroup,
{
return 0;
}
static int mem_cgroup_allow_attach(struct cgroup *cgroup,
struct cgroup_taskset *tset)
{
return 0;
}
static void mem_cgroup_cancel_attach(struct cgroup *cgroup,
struct cgroup_taskset *tset)
{
@ -6956,6 +6967,7 @@ struct cgroup_subsys mem_cgroup_subsys = {
.can_attach = mem_cgroup_can_attach,
.cancel_attach = mem_cgroup_cancel_attach,
.attach = mem_cgroup_move_task,
.allow_attach = mem_cgroup_allow_attach,
.bind = mem_cgroup_bind,
.base_cftypes = mem_cgroup_files,
.early_init = 0,

View File

@ -1174,6 +1174,9 @@ enum {
#endif
IPV6_SADDR_RULE_ORCHID,
IPV6_SADDR_RULE_PREFIX,
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
IPV6_SADDR_RULE_NOT_OPTIMISTIC,
#endif
IPV6_SADDR_RULE_MAX
};
@ -1201,6 +1204,15 @@ static inline int ipv6_saddr_preferred(int type)
return 0;
}
static inline bool ipv6_use_optimistic_addr(struct inet6_dev *idev)
{
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
return idev && idev->cnf.optimistic_dad && idev->cnf.use_optimistic;
#else
return false;
#endif
}
static int ipv6_get_saddr_eval(struct net *net,
struct ipv6_saddr_score *score,
struct ipv6_saddr_dst *dst,
@ -1261,10 +1273,16 @@ static int ipv6_get_saddr_eval(struct net *net,
score->scopedist = ret;
break;
case IPV6_SADDR_RULE_PREFERRED:
{
/* Rule 3: Avoid deprecated and optimistic addresses */
u8 avoid = IFA_F_DEPRECATED;
if (!ipv6_use_optimistic_addr(score->ifa->idev))
avoid |= IFA_F_OPTIMISTIC;
ret = ipv6_saddr_preferred(score->addr_type) ||
!(score->ifa->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC));
!(score->ifa->flags & avoid);
break;
}
#ifdef CONFIG_IPV6_MIP6
case IPV6_SADDR_RULE_HOA:
{
@ -1312,6 +1330,14 @@ static int ipv6_get_saddr_eval(struct net *net,
ret = score->ifa->prefix_len;
score->matchlen = ret;
break;
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
case IPV6_SADDR_RULE_NOT_OPTIMISTIC:
/* Optimistic addresses still have lower precedence than other
* preferred addresses.
*/
ret = !(score->ifa->flags & IFA_F_OPTIMISTIC);
break;
#endif
default:
ret = 0;
}
@ -3245,8 +3271,15 @@ static void addrconf_dad_start(struct inet6_ifaddr *ifp)
* Optimistic nodes can start receiving
* Frames right away
*/
if (ifp->flags & IFA_F_OPTIMISTIC)
if (ifp->flags & IFA_F_OPTIMISTIC) {
ip6_ins_rt(ifp->rt);
if (ipv6_use_optimistic_addr(idev)) {
/* Because optimistic nodes can use this address,
* notify listeners. If DAD fails, RTM_DELADDR is sent.
*/
ipv6_ifa_notify(RTM_NEWADDR, ifp);
}
}
addrconf_dad_kick(ifp);
out:
@ -4192,6 +4225,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
array[DEVCONF_OPTIMISTIC_DAD] = cnf->optimistic_dad;
array[DEVCONF_USE_OPTIMISTIC] = cnf->use_optimistic;
#endif
#ifdef CONFIG_IPV6_MROUTE
array[DEVCONF_MC_FORWARDING] = cnf->mc_forwarding;
@ -4926,6 +4960,14 @@ static struct addrconf_sysctl_table
.proc_handler = proc_dointvec,
},
{
.procname = "use_optimistic",
.data = &ipv6_devconf.use_optimistic,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
#endif
#ifdef CONFIG_IPV6_MROUTE
{

View File

@ -490,9 +490,6 @@ static int snd_compress_check_input(struct snd_compr_params *params)
if (params->codec.ch_in == 0 || params->codec.ch_out == 0)
return -EINVAL;
if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000))
return -EINVAL;
return 0;
}