Merge branch 'for-linus' into for-4.12/block
We've added a considerable amount of fixes for stalls and issues with the blk-mq scheduling in the 4.11 series since forking off the for-4.12/block branch. We need to do improvements on top of that for 4.12, so pull in the previous fixes to make our lives easier going forward. Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
@ -71,27 +71,17 @@ static int update_classid_sock(const void *v, struct file *file, unsigned n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void update_classid(struct cgroup_subsys_state *css, void *v)
|
||||
{
|
||||
struct css_task_iter it;
|
||||
struct task_struct *p;
|
||||
|
||||
css_task_iter_start(css, &it);
|
||||
while ((p = css_task_iter_next(&it))) {
|
||||
task_lock(p);
|
||||
iterate_fd(p->files, 0, update_classid_sock, v);
|
||||
task_unlock(p);
|
||||
}
|
||||
css_task_iter_end(&it);
|
||||
}
|
||||
|
||||
static void cgrp_attach(struct cgroup_taskset *tset)
|
||||
{
|
||||
struct cgroup_subsys_state *css;
|
||||
struct task_struct *p;
|
||||
|
||||
cgroup_taskset_first(tset, &css);
|
||||
update_classid(css,
|
||||
(void *)(unsigned long)css_cls_state(css)->classid);
|
||||
cgroup_taskset_for_each(p, css, tset) {
|
||||
task_lock(p);
|
||||
iterate_fd(p->files, 0, update_classid_sock,
|
||||
(void *)(unsigned long)css_cls_state(css)->classid);
|
||||
task_unlock(p);
|
||||
}
|
||||
}
|
||||
|
||||
static u64 read_classid(struct cgroup_subsys_state *css, struct cftype *cft)
|
||||
@ -103,12 +93,22 @@ static int write_classid(struct cgroup_subsys_state *css, struct cftype *cft,
|
||||
u64 value)
|
||||
{
|
||||
struct cgroup_cls_state *cs = css_cls_state(css);
|
||||
struct css_task_iter it;
|
||||
struct task_struct *p;
|
||||
|
||||
cgroup_sk_alloc_disable();
|
||||
|
||||
cs->classid = (u32)value;
|
||||
|
||||
update_classid(css, (void *)(unsigned long)cs->classid);
|
||||
css_task_iter_start(css, &it);
|
||||
while ((p = css_task_iter_next(&it))) {
|
||||
task_lock(p);
|
||||
iterate_fd(p->files, 0, update_classid_sock,
|
||||
(void *)(unsigned long)cs->classid);
|
||||
task_unlock(p);
|
||||
}
|
||||
css_task_iter_end(&it);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3694,6 +3694,15 @@ static void sock_rmem_free(struct sk_buff *skb)
|
||||
atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
|
||||
}
|
||||
|
||||
static void skb_set_err_queue(struct sk_buff *skb)
|
||||
{
|
||||
/* pkt_type of skbs received on local sockets is never PACKET_OUTGOING.
|
||||
* So, it is safe to (mis)use it to mark skbs on the error queue.
|
||||
*/
|
||||
skb->pkt_type = PACKET_OUTGOING;
|
||||
BUILD_BUG_ON(PACKET_OUTGOING == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: We dont mem charge error packets (no sk_forward_alloc changes)
|
||||
*/
|
||||
@ -3707,6 +3716,7 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
|
||||
skb->sk = sk;
|
||||
skb->destructor = sock_rmem_free;
|
||||
atomic_add(skb->truesize, &sk->sk_rmem_alloc);
|
||||
skb_set_err_queue(skb);
|
||||
|
||||
/* before exiting rcu section, make sure dst is refcounted */
|
||||
skb_dst_force(skb);
|
||||
@ -3783,16 +3793,20 @@ EXPORT_SYMBOL(skb_clone_sk);
|
||||
|
||||
static void __skb_complete_tx_timestamp(struct sk_buff *skb,
|
||||
struct sock *sk,
|
||||
int tstype)
|
||||
int tstype,
|
||||
bool opt_stats)
|
||||
{
|
||||
struct sock_exterr_skb *serr;
|
||||
int err;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct sock_exterr_skb) > sizeof(skb->cb));
|
||||
|
||||
serr = SKB_EXT_ERR(skb);
|
||||
memset(serr, 0, sizeof(*serr));
|
||||
serr->ee.ee_errno = ENOMSG;
|
||||
serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
|
||||
serr->ee.ee_info = tstype;
|
||||
serr->opt_stats = opt_stats;
|
||||
if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
|
||||
serr->ee.ee_data = skb_shinfo(skb)->tskey;
|
||||
if (sk->sk_protocol == IPPROTO_TCP &&
|
||||
@ -3833,7 +3847,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb,
|
||||
*/
|
||||
if (likely(atomic_inc_not_zero(&sk->sk_refcnt))) {
|
||||
*skb_hwtstamps(skb) = *hwtstamps;
|
||||
__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND);
|
||||
__skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false);
|
||||
sock_put(sk);
|
||||
}
|
||||
}
|
||||
@ -3844,7 +3858,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
|
||||
struct sock *sk, int tstype)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
bool tsonly;
|
||||
bool tsonly, opt_stats = false;
|
||||
|
||||
if (!sk)
|
||||
return;
|
||||
@ -3857,9 +3871,10 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
|
||||
#ifdef CONFIG_INET
|
||||
if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) &&
|
||||
sk->sk_protocol == IPPROTO_TCP &&
|
||||
sk->sk_type == SOCK_STREAM)
|
||||
sk->sk_type == SOCK_STREAM) {
|
||||
skb = tcp_get_timestamping_opt_stats(sk);
|
||||
else
|
||||
opt_stats = true;
|
||||
} else
|
||||
#endif
|
||||
skb = alloc_skb(0, GFP_ATOMIC);
|
||||
} else {
|
||||
@ -3878,7 +3893,7 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
|
||||
else
|
||||
skb->tstamp = ktime_get_real();
|
||||
|
||||
__skb_complete_tx_timestamp(skb, sk, tstype);
|
||||
__skb_complete_tx_timestamp(skb, sk, tstype, opt_stats);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__skb_tstamp_tx);
|
||||
|
||||
|
@ -1442,6 +1442,11 @@ static void __sk_destruct(struct rcu_head *head)
|
||||
pr_debug("%s: optmem leakage (%d bytes) detected\n",
|
||||
__func__, atomic_read(&sk->sk_omem_alloc));
|
||||
|
||||
if (sk->sk_frag.page) {
|
||||
put_page(sk->sk_frag.page);
|
||||
sk->sk_frag.page = NULL;
|
||||
}
|
||||
|
||||
if (sk->sk_peer_cred)
|
||||
put_cred(sk->sk_peer_cred);
|
||||
put_pid(sk->sk_peer_pid);
|
||||
@ -1539,6 +1544,12 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
|
||||
is_charged = sk_filter_charge(newsk, filter);
|
||||
|
||||
if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
|
||||
/* We need to make sure that we don't uncharge the new
|
||||
* socket if we couldn't charge it in the first place
|
||||
* as otherwise we uncharge the parent's filter.
|
||||
*/
|
||||
if (!is_charged)
|
||||
RCU_INIT_POINTER(newsk->sk_filter, NULL);
|
||||
sk_free_unlock_clone(newsk);
|
||||
newsk = NULL;
|
||||
goto out;
|
||||
@ -2787,11 +2798,6 @@ void sk_common_release(struct sock *sk)
|
||||
|
||||
sk_refcnt_debug_release(sk);
|
||||
|
||||
if (sk->sk_frag.page) {
|
||||
put_page(sk->sk_frag.page);
|
||||
sk->sk_frag.page = NULL;
|
||||
}
|
||||
|
||||
sock_put(sk);
|
||||
}
|
||||
EXPORT_SYMBOL(sk_common_release);
|
||||
|
Reference in New Issue
Block a user