mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-23 04:59:05 -04:00
Linux 4.17-rc5
-----BEGIN PGP SIGNATURE----- iQFSBAABCAA8FiEEq68RxlopcLEwq+PEeb4+QwBBGIYFAlr4xw8eHHRvcnZhbGRz QGxpbnV4LWZvdW5kYXRpb24ub3JnAAoJEHm+PkMAQRiGNYoH/1d5zyMpVJVUKZ0K LuEctCGby1PjSvSOhmMuxFVagFAqfBJXmwWTeohLfLG48r/Yk0AsZQ5HH13/8baj k/T8UgUvKZKustndCRp+joQ3Pa1ZpcIFaWRvB8pKFCefJ/F/Lj4B4X1HYI7vLq0K /ZBXUdy3ry0lcVuypnaARYAb2O7l/nyZIjZ3FhiuyymWe7Jpo+G7VK922LOMSX/y VYFZCWa8nxN+yFhO0ao9X5k7ggIiUrEBtbfNrk19VtAn0hx+OYKW2KfJK/eHNey/ CKrOT+KAxU8VU29AEIbYzlL3yrQmULcEoIDiqJ/6m5m6JwsEbP6EqQHs0TiuQFpq A0MO9rw= =yjUP -----END PGP SIGNATURE----- Merge tag 'v4.17-rc5' into sched/core, to pick up fixes and dependencies Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
dfd5c3ea64
554 changed files with 4133 additions and 2187 deletions
|
|
@ -476,7 +476,7 @@ static u32 prog_fd_array_sys_lookup_elem(void *ptr)
|
|||
}
|
||||
|
||||
/* decrement refcnt of all bpf_progs that are stored in this map */
|
||||
void bpf_fd_array_map_clear(struct bpf_map *map)
|
||||
static void bpf_fd_array_map_clear(struct bpf_map *map)
|
||||
{
|
||||
struct bpf_array *array = container_of(map, struct bpf_array, map);
|
||||
int i;
|
||||
|
|
@ -495,6 +495,7 @@ const struct bpf_map_ops prog_array_map_ops = {
|
|||
.map_fd_get_ptr = prog_fd_array_get_ptr,
|
||||
.map_fd_put_ptr = prog_fd_array_put_ptr,
|
||||
.map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem,
|
||||
.map_release_uref = bpf_fd_array_map_clear,
|
||||
};
|
||||
|
||||
static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
#include <net/tcp.h>
|
||||
#include <linux/ptr_ring.h>
|
||||
#include <net/inet_common.h>
|
||||
#include <linux/sched/signal.h>
|
||||
|
||||
#define SOCK_CREATE_FLAG_MASK \
|
||||
(BPF_F_NUMA_NODE | BPF_F_RDONLY | BPF_F_WRONLY)
|
||||
|
|
@ -325,6 +326,9 @@ retry:
|
|||
if (ret > 0) {
|
||||
if (apply)
|
||||
apply_bytes -= ret;
|
||||
|
||||
sg->offset += ret;
|
||||
sg->length -= ret;
|
||||
size -= ret;
|
||||
offset += ret;
|
||||
if (uncharge)
|
||||
|
|
@ -332,8 +336,6 @@ retry:
|
|||
goto retry;
|
||||
}
|
||||
|
||||
sg->length = size;
|
||||
sg->offset = offset;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -391,7 +393,8 @@ static void return_mem_sg(struct sock *sk, int bytes, struct sk_msg_buff *md)
|
|||
} while (i != md->sg_end);
|
||||
}
|
||||
|
||||
static void free_bytes_sg(struct sock *sk, int bytes, struct sk_msg_buff *md)
|
||||
static void free_bytes_sg(struct sock *sk, int bytes,
|
||||
struct sk_msg_buff *md, bool charge)
|
||||
{
|
||||
struct scatterlist *sg = md->sg_data;
|
||||
int i = md->sg_start, free;
|
||||
|
|
@ -401,11 +404,13 @@ static void free_bytes_sg(struct sock *sk, int bytes, struct sk_msg_buff *md)
|
|||
if (bytes < free) {
|
||||
sg[i].length -= bytes;
|
||||
sg[i].offset += bytes;
|
||||
sk_mem_uncharge(sk, bytes);
|
||||
if (charge)
|
||||
sk_mem_uncharge(sk, bytes);
|
||||
break;
|
||||
}
|
||||
|
||||
sk_mem_uncharge(sk, sg[i].length);
|
||||
if (charge)
|
||||
sk_mem_uncharge(sk, sg[i].length);
|
||||
put_page(sg_page(&sg[i]));
|
||||
bytes -= sg[i].length;
|
||||
sg[i].length = 0;
|
||||
|
|
@ -416,6 +421,7 @@ static void free_bytes_sg(struct sock *sk, int bytes, struct sk_msg_buff *md)
|
|||
if (i == MAX_SKB_FRAGS)
|
||||
i = 0;
|
||||
}
|
||||
md->sg_start = i;
|
||||
}
|
||||
|
||||
static int free_sg(struct sock *sk, int start, struct sk_msg_buff *md)
|
||||
|
|
@ -523,8 +529,6 @@ static int bpf_tcp_ingress(struct sock *sk, int apply_bytes,
|
|||
i = md->sg_start;
|
||||
|
||||
do {
|
||||
r->sg_data[i] = md->sg_data[i];
|
||||
|
||||
size = (apply && apply_bytes < md->sg_data[i].length) ?
|
||||
apply_bytes : md->sg_data[i].length;
|
||||
|
||||
|
|
@ -535,6 +539,7 @@ static int bpf_tcp_ingress(struct sock *sk, int apply_bytes,
|
|||
}
|
||||
|
||||
sk_mem_charge(sk, size);
|
||||
r->sg_data[i] = md->sg_data[i];
|
||||
r->sg_data[i].length = size;
|
||||
md->sg_data[i].length -= size;
|
||||
md->sg_data[i].offset += size;
|
||||
|
|
@ -575,10 +580,10 @@ static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send,
|
|||
struct sk_msg_buff *md,
|
||||
int flags)
|
||||
{
|
||||
bool ingress = !!(md->flags & BPF_F_INGRESS);
|
||||
struct smap_psock *psock;
|
||||
struct scatterlist *sg;
|
||||
int i, err, free = 0;
|
||||
bool ingress = !!(md->flags & BPF_F_INGRESS);
|
||||
int err = 0;
|
||||
|
||||
sg = md->sg_data;
|
||||
|
||||
|
|
@ -606,16 +611,8 @@ static int bpf_tcp_sendmsg_do_redirect(struct sock *sk, int send,
|
|||
out_rcu:
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
i = md->sg_start;
|
||||
while (sg[i].length) {
|
||||
free += sg[i].length;
|
||||
put_page(sg_page(&sg[i]));
|
||||
sg[i].length = 0;
|
||||
i++;
|
||||
if (i == MAX_SKB_FRAGS)
|
||||
i = 0;
|
||||
}
|
||||
return free;
|
||||
free_bytes_sg(NULL, send, md, false);
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline void bpf_md_init(struct smap_psock *psock)
|
||||
|
|
@ -700,19 +697,26 @@ more_data:
|
|||
err = bpf_tcp_sendmsg_do_redirect(redir, send, m, flags);
|
||||
lock_sock(sk);
|
||||
|
||||
if (unlikely(err < 0)) {
|
||||
free_start_sg(sk, m);
|
||||
psock->sg_size = 0;
|
||||
if (!cork)
|
||||
*copied -= send;
|
||||
} else {
|
||||
psock->sg_size -= send;
|
||||
}
|
||||
|
||||
if (cork) {
|
||||
free_start_sg(sk, m);
|
||||
psock->sg_size = 0;
|
||||
kfree(m);
|
||||
m = NULL;
|
||||
err = 0;
|
||||
}
|
||||
if (unlikely(err))
|
||||
*copied -= err;
|
||||
else
|
||||
psock->sg_size -= send;
|
||||
break;
|
||||
case __SK_DROP:
|
||||
default:
|
||||
free_bytes_sg(sk, send, m);
|
||||
free_bytes_sg(sk, send, m, true);
|
||||
apply_bytes_dec(psock, send);
|
||||
*copied -= send;
|
||||
psock->sg_size -= send;
|
||||
|
|
@ -732,6 +736,26 @@ out_err:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int bpf_wait_data(struct sock *sk,
|
||||
struct smap_psock *psk, int flags,
|
||||
long timeo, int *err)
|
||||
{
|
||||
int rc;
|
||||
|
||||
DEFINE_WAIT_FUNC(wait, woken_wake_function);
|
||||
|
||||
add_wait_queue(sk_sleep(sk), &wait);
|
||||
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
|
||||
rc = sk_wait_event(sk, &timeo,
|
||||
!list_empty(&psk->ingress) ||
|
||||
!skb_queue_empty(&sk->sk_receive_queue),
|
||||
&wait);
|
||||
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
|
||||
remove_wait_queue(sk_sleep(sk), &wait);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
|
||||
int nonblock, int flags, int *addr_len)
|
||||
{
|
||||
|
|
@ -755,6 +779,7 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
|
|||
return tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
|
||||
|
||||
lock_sock(sk);
|
||||
bytes_ready:
|
||||
while (copied != len) {
|
||||
struct scatterlist *sg;
|
||||
struct sk_msg_buff *md;
|
||||
|
|
@ -809,6 +834,28 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
|
|||
}
|
||||
}
|
||||
|
||||
if (!copied) {
|
||||
long timeo;
|
||||
int data;
|
||||
int err = 0;
|
||||
|
||||
timeo = sock_rcvtimeo(sk, nonblock);
|
||||
data = bpf_wait_data(sk, psock, flags, timeo, &err);
|
||||
|
||||
if (data) {
|
||||
if (!skb_queue_empty(&sk->sk_receive_queue)) {
|
||||
release_sock(sk);
|
||||
smap_release_sock(psock, sk);
|
||||
copied = tcp_recvmsg(sk, msg, len, nonblock, flags, addr_len);
|
||||
return copied;
|
||||
}
|
||||
goto bytes_ready;
|
||||
}
|
||||
|
||||
if (err)
|
||||
copied = err;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
smap_release_sock(psock, sk);
|
||||
return copied;
|
||||
|
|
@ -1831,7 +1878,7 @@ static int sock_map_update_elem(struct bpf_map *map,
|
|||
return err;
|
||||
}
|
||||
|
||||
static void sock_map_release(struct bpf_map *map, struct file *map_file)
|
||||
static void sock_map_release(struct bpf_map *map)
|
||||
{
|
||||
struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
|
||||
struct bpf_prog *orig;
|
||||
|
|
@ -1855,7 +1902,7 @@ const struct bpf_map_ops sock_map_ops = {
|
|||
.map_get_next_key = sock_map_get_next_key,
|
||||
.map_update_elem = sock_map_update_elem,
|
||||
.map_delete_elem = sock_map_delete_elem,
|
||||
.map_release = sock_map_release,
|
||||
.map_release_uref = sock_map_release,
|
||||
};
|
||||
|
||||
BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/cred.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
|
||||
(map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
|
||||
|
|
@ -102,12 +103,14 @@ const struct bpf_map_ops bpf_map_offload_ops = {
|
|||
static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
|
||||
{
|
||||
const struct bpf_map_ops *ops;
|
||||
u32 type = attr->map_type;
|
||||
struct bpf_map *map;
|
||||
int err;
|
||||
|
||||
if (attr->map_type >= ARRAY_SIZE(bpf_map_types))
|
||||
if (type >= ARRAY_SIZE(bpf_map_types))
|
||||
return ERR_PTR(-EINVAL);
|
||||
ops = bpf_map_types[attr->map_type];
|
||||
type = array_index_nospec(type, ARRAY_SIZE(bpf_map_types));
|
||||
ops = bpf_map_types[type];
|
||||
if (!ops)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
|
|
@ -122,7 +125,7 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
|
|||
if (IS_ERR(map))
|
||||
return map;
|
||||
map->ops = ops;
|
||||
map->map_type = attr->map_type;
|
||||
map->map_type = type;
|
||||
return map;
|
||||
}
|
||||
|
||||
|
|
@ -257,8 +260,8 @@ static void bpf_map_free_deferred(struct work_struct *work)
|
|||
static void bpf_map_put_uref(struct bpf_map *map)
|
||||
{
|
||||
if (atomic_dec_and_test(&map->usercnt)) {
|
||||
if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY)
|
||||
bpf_fd_array_map_clear(map);
|
||||
if (map->ops->map_release_uref)
|
||||
map->ops->map_release_uref(map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -871,11 +874,17 @@ static const struct bpf_prog_ops * const bpf_prog_types[] = {
|
|||
|
||||
static int find_prog_type(enum bpf_prog_type type, struct bpf_prog *prog)
|
||||
{
|
||||
if (type >= ARRAY_SIZE(bpf_prog_types) || !bpf_prog_types[type])
|
||||
const struct bpf_prog_ops *ops;
|
||||
|
||||
if (type >= ARRAY_SIZE(bpf_prog_types))
|
||||
return -EINVAL;
|
||||
type = array_index_nospec(type, ARRAY_SIZE(bpf_prog_types));
|
||||
ops = bpf_prog_types[type];
|
||||
if (!ops)
|
||||
return -EINVAL;
|
||||
|
||||
if (!bpf_prog_is_dev_bound(prog->aux))
|
||||
prog->aux->ops = bpf_prog_types[type];
|
||||
prog->aux->ops = ops;
|
||||
else
|
||||
prog->aux->ops = &bpf_offload_prog_ops;
|
||||
prog->type = type;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ int compat_get_timex(struct timex *txc, const struct compat_timex __user *utp)
|
|||
{
|
||||
struct compat_timex tx32;
|
||||
|
||||
memset(txc, 0, sizeof(struct timex));
|
||||
if (copy_from_user(&tx32, utp, sizeof(struct compat_timex)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/circ_buf.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
|
@ -867,8 +868,10 @@ perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff)
|
|||
return NULL;
|
||||
|
||||
/* AUX space */
|
||||
if (pgoff >= rb->aux_pgoff)
|
||||
return virt_to_page(rb->aux_pages[pgoff - rb->aux_pgoff]);
|
||||
if (pgoff >= rb->aux_pgoff) {
|
||||
int aux_pgoff = array_index_nospec(pgoff - rb->aux_pgoff, rb->aux_nr_pages);
|
||||
return virt_to_page(rb->aux_pages[aux_pgoff]);
|
||||
}
|
||||
}
|
||||
|
||||
return __perf_mmap_to_page(rb, pgoff);
|
||||
|
|
|
|||
|
|
@ -3517,6 +3517,11 @@ static noinline int do_init_module(struct module *mod)
|
|||
* walking this with preempt disabled. In all the failure paths, we
|
||||
* call synchronize_sched(), but we don't want to slow down the success
|
||||
* path, so use actual RCU here.
|
||||
* Note that module_alloc() on most architectures creates W+X page
|
||||
* mappings which won't be cleaned up until do_free_init() runs. Any
|
||||
* code such as mark_rodata_ro() which depends on those mappings to
|
||||
* be cleaned up needs to sync with the queued work - ie
|
||||
* rcu_barrier_sched()
|
||||
*/
|
||||
call_rcu_sched(&freeinit->rcu, do_free_init);
|
||||
mutex_unlock(&module_mutex);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
/*
|
||||
* Auto-group scheduling implementation:
|
||||
*/
|
||||
#include <linux/nospec.h>
|
||||
#include "sched.h"
|
||||
|
||||
unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
|
||||
|
|
@ -209,7 +210,7 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice)
|
|||
static unsigned long next = INITIAL_JIFFIES;
|
||||
struct autogroup *ag;
|
||||
unsigned long shares;
|
||||
int err;
|
||||
int err, idx;
|
||||
|
||||
if (nice < MIN_NICE || nice > MAX_NICE)
|
||||
return -EINVAL;
|
||||
|
|
@ -227,7 +228,9 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice)
|
|||
|
||||
next = HZ / 10 + jiffies;
|
||||
ag = autogroup_task_get(p);
|
||||
shares = scale_load(sched_prio_to_weight[nice + 20]);
|
||||
|
||||
idx = array_index_nospec(nice + 20, 40);
|
||||
shares = scale_load(sched_prio_to_weight[idx]);
|
||||
|
||||
down_write(&ag->lock);
|
||||
err = sched_group_set_shares(ag->tg, shares);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "sched.h"
|
||||
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/nospec.h>
|
||||
|
||||
#include <asm/switch_to.h>
|
||||
#include <asm/tlb.h>
|
||||
|
|
@ -6926,11 +6927,15 @@ static int cpu_weight_nice_write_s64(struct cgroup_subsys_state *css,
|
|||
struct cftype *cft, s64 nice)
|
||||
{
|
||||
unsigned long weight;
|
||||
int idx;
|
||||
|
||||
if (nice < MIN_NICE || nice > MAX_NICE)
|
||||
return -ERANGE;
|
||||
|
||||
weight = sched_prio_to_weight[NICE_TO_PRIO(nice) - MAX_RT_PRIO];
|
||||
idx = NICE_TO_PRIO(nice) - MAX_RT_PRIO;
|
||||
idx = array_index_nospec(idx, 40);
|
||||
weight = sched_prio_to_weight[idx];
|
||||
|
||||
return sched_group_set_shares(css_tg(css), scale_load(weight));
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -305,7 +305,8 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
|
|||
* Do not reduce the frequency if the CPU has not been idle
|
||||
* recently, as the reduction is likely to be premature then.
|
||||
*/
|
||||
if (busy && next_f < sg_policy->next_freq) {
|
||||
if (busy && next_f < sg_policy->next_freq &&
|
||||
sg_policy->next_freq != UINT_MAX) {
|
||||
next_f = sg_policy->next_freq;
|
||||
|
||||
/* Reset cached freq as next_freq has changed */
|
||||
|
|
@ -396,19 +397,6 @@ static void sugov_irq_work(struct irq_work *irq_work)
|
|||
|
||||
sg_policy = container_of(irq_work, struct sugov_policy, irq_work);
|
||||
|
||||
/*
|
||||
* For RT tasks, the schedutil governor shoots the frequency to maximum.
|
||||
* Special care must be taken to ensure that this kthread doesn't result
|
||||
* in the same behavior.
|
||||
*
|
||||
* This is (mostly) guaranteed by the work_in_progress flag. The flag is
|
||||
* updated only at the end of the sugov_work() function and before that
|
||||
* the schedutil governor rejects all other frequency scaling requests.
|
||||
*
|
||||
* There is a very rare case though, where the RT thread yields right
|
||||
* after the work_in_progress flag is cleared. The effects of that are
|
||||
* neglected for now.
|
||||
*/
|
||||
kthread_queue_work(&sg_policy->worker, &sg_policy->work);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1854,7 +1854,6 @@ static int task_numa_migrate(struct task_struct *p)
|
|||
static void numa_migrate_preferred(struct task_struct *p)
|
||||
{
|
||||
unsigned long interval = HZ;
|
||||
unsigned long numa_migrate_retry;
|
||||
|
||||
/* This task has no NUMA fault statistics yet */
|
||||
if (unlikely(p->numa_preferred_nid == -1 || !p->numa_faults))
|
||||
|
|
@ -1862,18 +1861,7 @@ static void numa_migrate_preferred(struct task_struct *p)
|
|||
|
||||
/* Periodically retry migrating the task to the preferred node */
|
||||
interval = min(interval, msecs_to_jiffies(p->numa_scan_period) / 16);
|
||||
numa_migrate_retry = jiffies + interval;
|
||||
|
||||
/*
|
||||
* Check that the new retry threshold is after the current one. If
|
||||
* the retry is in the future, it implies that wake_affine has
|
||||
* temporarily asked NUMA balancing to backoff from placement.
|
||||
*/
|
||||
if (numa_migrate_retry > p->numa_migrate_retry)
|
||||
return;
|
||||
|
||||
/* Safe to try placing the task on the preferred node */
|
||||
p->numa_migrate_retry = numa_migrate_retry;
|
||||
p->numa_migrate_retry = jiffies + interval;
|
||||
|
||||
/* Success if task is already running on preferred CPU */
|
||||
if (task_node(p) == p->numa_preferred_nid)
|
||||
|
|
@ -5922,48 +5910,6 @@ wake_affine_weight(struct sched_domain *sd, struct task_struct *p,
|
|||
return this_eff_load < prev_eff_load ? this_cpu : nr_cpumask_bits;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NUMA_BALANCING
|
||||
static void
|
||||
update_wa_numa_placement(struct task_struct *p, int prev_cpu, int target)
|
||||
{
|
||||
unsigned long interval;
|
||||
|
||||
if (!static_branch_likely(&sched_numa_balancing))
|
||||
return;
|
||||
|
||||
/* If balancing has no preference then continue gathering data */
|
||||
if (p->numa_preferred_nid == -1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the wakeup is not affecting locality then it is neutral from
|
||||
* the perspective of NUMA balacing so continue gathering data.
|
||||
*/
|
||||
if (cpu_to_node(prev_cpu) == cpu_to_node(target))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Temporarily prevent NUMA balancing trying to place waker/wakee after
|
||||
* wakee has been moved by wake_affine. This will potentially allow
|
||||
* related tasks to converge and update their data placement. The
|
||||
* 4 * numa_scan_period is to allow the two-pass filter to migrate
|
||||
* hot data to the wakers node.
|
||||
*/
|
||||
interval = max(sysctl_numa_balancing_scan_delay,
|
||||
p->numa_scan_period << 2);
|
||||
p->numa_migrate_retry = jiffies + msecs_to_jiffies(interval);
|
||||
|
||||
interval = max(sysctl_numa_balancing_scan_delay,
|
||||
current->numa_scan_period << 2);
|
||||
current->numa_migrate_retry = jiffies + msecs_to_jiffies(interval);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
update_wa_numa_placement(struct task_struct *p, int prev_cpu, int target)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int wake_affine(struct sched_domain *sd, struct task_struct *p,
|
||||
int this_cpu, int prev_cpu, int sync)
|
||||
{
|
||||
|
|
@ -5979,7 +5925,6 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p,
|
|||
if (target == nr_cpumask_bits)
|
||||
return prev_cpu;
|
||||
|
||||
update_wa_numa_placement(p, prev_cpu, target);
|
||||
schedstat_inc(sd->ttwu_move_affine);
|
||||
schedstat_inc(p->se.statistics.nr_wakeups_affine);
|
||||
return target;
|
||||
|
|
|
|||
|
|
@ -119,6 +119,16 @@ static DEFINE_SPINLOCK(watchdog_lock);
|
|||
static int watchdog_running;
|
||||
static atomic_t watchdog_reset_pending;
|
||||
|
||||
static void inline clocksource_watchdog_lock(unsigned long *flags)
|
||||
{
|
||||
spin_lock_irqsave(&watchdog_lock, *flags);
|
||||
}
|
||||
|
||||
static void inline clocksource_watchdog_unlock(unsigned long *flags)
|
||||
{
|
||||
spin_unlock_irqrestore(&watchdog_lock, *flags);
|
||||
}
|
||||
|
||||
static int clocksource_watchdog_kthread(void *data);
|
||||
static void __clocksource_change_rating(struct clocksource *cs, int rating);
|
||||
|
||||
|
|
@ -142,9 +152,19 @@ static void __clocksource_unstable(struct clocksource *cs)
|
|||
cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG);
|
||||
cs->flags |= CLOCK_SOURCE_UNSTABLE;
|
||||
|
||||
/*
|
||||
* If the clocksource is registered clocksource_watchdog_kthread() will
|
||||
* re-rate and re-select.
|
||||
*/
|
||||
if (list_empty(&cs->list)) {
|
||||
cs->rating = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cs->mark_unstable)
|
||||
cs->mark_unstable(cs);
|
||||
|
||||
/* kick clocksource_watchdog_kthread() */
|
||||
if (finished_booting)
|
||||
schedule_work(&watchdog_work);
|
||||
}
|
||||
|
|
@ -153,10 +173,8 @@ static void __clocksource_unstable(struct clocksource *cs)
|
|||
* clocksource_mark_unstable - mark clocksource unstable via watchdog
|
||||
* @cs: clocksource to be marked unstable
|
||||
*
|
||||
* This function is called instead of clocksource_change_rating from
|
||||
* cpu hotplug code to avoid a deadlock between the clocksource mutex
|
||||
* and the cpu hotplug mutex. It defers the update of the clocksource
|
||||
* to the watchdog thread.
|
||||
* This function is called by the x86 TSC code to mark clocksources as unstable;
|
||||
* it defers demotion and re-selection to a kthread.
|
||||
*/
|
||||
void clocksource_mark_unstable(struct clocksource *cs)
|
||||
{
|
||||
|
|
@ -164,7 +182,7 @@ void clocksource_mark_unstable(struct clocksource *cs)
|
|||
|
||||
spin_lock_irqsave(&watchdog_lock, flags);
|
||||
if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) {
|
||||
if (list_empty(&cs->wd_list))
|
||||
if (!list_empty(&cs->list) && list_empty(&cs->wd_list))
|
||||
list_add(&cs->wd_list, &watchdog_list);
|
||||
__clocksource_unstable(cs);
|
||||
}
|
||||
|
|
@ -319,9 +337,8 @@ static void clocksource_resume_watchdog(void)
|
|||
|
||||
static void clocksource_enqueue_watchdog(struct clocksource *cs)
|
||||
{
|
||||
unsigned long flags;
|
||||
INIT_LIST_HEAD(&cs->wd_list);
|
||||
|
||||
spin_lock_irqsave(&watchdog_lock, flags);
|
||||
if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
|
||||
/* cs is a clocksource to be watched. */
|
||||
list_add(&cs->wd_list, &watchdog_list);
|
||||
|
|
@ -331,7 +348,6 @@ static void clocksource_enqueue_watchdog(struct clocksource *cs)
|
|||
if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS)
|
||||
cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES;
|
||||
}
|
||||
spin_unlock_irqrestore(&watchdog_lock, flags);
|
||||
}
|
||||
|
||||
static void clocksource_select_watchdog(bool fallback)
|
||||
|
|
@ -373,9 +389,6 @@ static void clocksource_select_watchdog(bool fallback)
|
|||
|
||||
static void clocksource_dequeue_watchdog(struct clocksource *cs)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&watchdog_lock, flags);
|
||||
if (cs != watchdog) {
|
||||
if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) {
|
||||
/* cs is a watched clocksource. */
|
||||
|
|
@ -384,21 +397,19 @@ static void clocksource_dequeue_watchdog(struct clocksource *cs)
|
|||
clocksource_stop_watchdog();
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&watchdog_lock, flags);
|
||||
}
|
||||
|
||||
static int __clocksource_watchdog_kthread(void)
|
||||
{
|
||||
struct clocksource *cs, *tmp;
|
||||
unsigned long flags;
|
||||
LIST_HEAD(unstable);
|
||||
int select = 0;
|
||||
|
||||
spin_lock_irqsave(&watchdog_lock, flags);
|
||||
list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) {
|
||||
if (cs->flags & CLOCK_SOURCE_UNSTABLE) {
|
||||
list_del_init(&cs->wd_list);
|
||||
list_add(&cs->wd_list, &unstable);
|
||||
__clocksource_change_rating(cs, 0);
|
||||
select = 1;
|
||||
}
|
||||
if (cs->flags & CLOCK_SOURCE_RESELECT) {
|
||||
|
|
@ -410,11 +421,6 @@ static int __clocksource_watchdog_kthread(void)
|
|||
clocksource_stop_watchdog();
|
||||
spin_unlock_irqrestore(&watchdog_lock, flags);
|
||||
|
||||
/* Needs to be done outside of watchdog lock */
|
||||
list_for_each_entry_safe(cs, tmp, &unstable, wd_list) {
|
||||
list_del_init(&cs->wd_list);
|
||||
__clocksource_change_rating(cs, 0);
|
||||
}
|
||||
return select;
|
||||
}
|
||||
|
||||
|
|
@ -447,6 +453,9 @@ static inline int __clocksource_watchdog_kthread(void) { return 0; }
|
|||
static bool clocksource_is_watchdog(struct clocksource *cs) { return false; }
|
||||
void clocksource_mark_unstable(struct clocksource *cs) { }
|
||||
|
||||
static void inline clocksource_watchdog_lock(unsigned long *flags) { }
|
||||
static void inline clocksource_watchdog_unlock(unsigned long *flags) { }
|
||||
|
||||
#endif /* CONFIG_CLOCKSOURCE_WATCHDOG */
|
||||
|
||||
/**
|
||||
|
|
@ -779,14 +788,19 @@ EXPORT_SYMBOL_GPL(__clocksource_update_freq_scale);
|
|||
*/
|
||||
int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/* Initialize mult/shift and max_idle_ns */
|
||||
__clocksource_update_freq_scale(cs, scale, freq);
|
||||
|
||||
/* Add clocksource to the clocksource list */
|
||||
mutex_lock(&clocksource_mutex);
|
||||
|
||||
clocksource_watchdog_lock(&flags);
|
||||
clocksource_enqueue(cs);
|
||||
clocksource_enqueue_watchdog(cs);
|
||||
clocksource_watchdog_unlock(&flags);
|
||||
|
||||
clocksource_select();
|
||||
clocksource_select_watchdog(false);
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
|
|
@ -808,8 +822,13 @@ static void __clocksource_change_rating(struct clocksource *cs, int rating)
|
|||
*/
|
||||
void clocksource_change_rating(struct clocksource *cs, int rating)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&clocksource_mutex);
|
||||
clocksource_watchdog_lock(&flags);
|
||||
__clocksource_change_rating(cs, rating);
|
||||
clocksource_watchdog_unlock(&flags);
|
||||
|
||||
clocksource_select();
|
||||
clocksource_select_watchdog(false);
|
||||
mutex_unlock(&clocksource_mutex);
|
||||
|
|
@ -821,6 +840,8 @@ EXPORT_SYMBOL(clocksource_change_rating);
|
|||
*/
|
||||
static int clocksource_unbind(struct clocksource *cs)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (clocksource_is_watchdog(cs)) {
|
||||
/* Select and try to install a replacement watchdog. */
|
||||
clocksource_select_watchdog(true);
|
||||
|
|
@ -834,8 +855,12 @@ static int clocksource_unbind(struct clocksource *cs)
|
|||
if (curr_clocksource == cs)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
clocksource_watchdog_lock(&flags);
|
||||
clocksource_dequeue_watchdog(cs);
|
||||
list_del_init(&cs->list);
|
||||
clocksource_watchdog_unlock(&flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5514,10 +5514,10 @@ static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer)
|
|||
ftrace_create_filter_files(&global_ops, d_tracer);
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
trace_create_file("set_graph_function", 0444, d_tracer,
|
||||
trace_create_file("set_graph_function", 0644, d_tracer,
|
||||
NULL,
|
||||
&ftrace_graph_fops);
|
||||
trace_create_file("set_graph_notrace", 0444, d_tracer,
|
||||
trace_create_file("set_graph_notrace", 0644, d_tracer,
|
||||
NULL,
|
||||
&ftrace_graph_notrace_fops);
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
||||
|
|
|
|||
|
|
@ -762,6 +762,9 @@ static int regex_match_full(char *str, struct regex *r, int len)
|
|||
|
||||
static int regex_match_front(char *str, struct regex *r, int len)
|
||||
{
|
||||
if (len < r->len)
|
||||
return 0;
|
||||
|
||||
if (strncmp(str, r->pattern, r->len) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -472,7 +472,7 @@ static __init int stack_trace_init(void)
|
|||
NULL, &stack_trace_fops);
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
trace_create_file("stack_trace_filter", 0444, d_tracer,
|
||||
trace_create_file("stack_trace_filter", 0644, d_tracer,
|
||||
&trace_ops, &stack_trace_filter_fops);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue