* Re: 3.2.8/amd64 full interrupt hangs and deadlocks under big network copies (page allocation failure)
From: Eric Dumazet @ 2012-04-10 6:11 UTC (permalink / raw)
To: Marc MERLIN
Cc: David Miller, Larry.Finger, bhutchings, linux-wireless, netdev
In-Reply-To: <20120410051127.GA32048@merlins.org>
On Mon, 2012-04-09 at 22:11 -0700, Marc MERLIN wrote:
> On Tue, Apr 10, 2012 at 05:56:20AM +0200, Eric Dumazet wrote:
> > > What wireless device are we dealing with again?
> >
> > Problem seems related to tailroom needed by mac80211
> > (IEEE80211_ENCRYPT_TAILROOM = 18 bytes)
> >
> > So we must reallocate skb->head, thats impressive nobody cares.
> >
> > [ 3007.249687] ieee80211_skb_resize(skb=ffff8802329846e8) cloned=1 head_need=0 tail_need=18 skb->len=1494 ksize=4096 tailroom=0 headroom=2282
> > [ 3007.249693] ieee80211_skb_resize(skb=ffff8802329846e8) cloned=0 head_need=0 tail_need=0 skb->len=1526 ksize=8192 tailroom=64 headroom=2250
> >
> > Ouch... skb_tailroom() seems wrong ... it seems pskb_expand_head() is really suboptimal.
> >
> > It appears tcp_sendmsg() tries to fill skb completely, with no available tailroom :
> >
> > if (skb_tailroom(skb) > 0) {
> > /* We have some space in skb head. Superb! */
> > if (copy > skb_tailroom(skb))
> > copy = skb_tailroom(skb);
> > err = skb_add_data_nocache(sk, skb, from, copy);
> > if (err)
> > goto do_fault;
> > } else {
> >
> > Shouldnt we take into account dev->needed_tailroom ?
> >
> > I'll submit a pskb_expand_head() fix asap.
>
> Thanks for finding this.
>
> To answer an earlier question, I tried the non wireless case too.
>
> The problem is harder to reproduce over e1000e though, I just got two short
> hangs where my mouse cursor was hung for 5-10 seconds, but nothing in
> syslog/dmesg this time.
>
> I'm pretty sure this older log below did happen on e1000e with wireless disabled
> though (but it had a taint 'O'):
>
> If that helps, my earlier message had the traces below.
>
> I can report back when you have a patch you'd like me to try out.
Hi Marc
Please try following patch, as it solved the problem for me (no more
order-1 allocations in tx path)
Thanks !
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3337027..70a3f8d 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -481,6 +481,7 @@ struct sk_buff {
union {
__u32 mark;
__u32 dropcount;
+ __u32 avail_size;
};
sk_buff_data_t transport_header;
@@ -1366,6 +1367,18 @@ static inline int skb_tailroom(const struct sk_buff *skb)
}
/**
+ * skb_availroom - bytes at buffer end
+ * @skb: buffer to check
+ *
+ * Return the number of bytes of free space at the tail of an sk_buff
+ * allocated by sk_stream_alloc()
+ */
+static inline int skb_availroom(const struct sk_buff *skb)
+{
+ return skb_is_nonlinear(skb) ? 0 : skb->avail_size - skb->len;
+}
+
+/**
* skb_reserve - adjust headroom
* @skb: buffer to alter
* @len: bytes to move
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index baf8d28..1887454 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -952,9 +952,11 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
goto adjust_others;
}
- data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+ data = kmalloc(size + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
+ gfp_mask);
if (!data)
goto nodata;
+ size = ksize(data) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
/* Copy only real data... and, alas, header. This should be
* optimized for the cases when header is void.
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5d54ed3..87f497f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -701,11 +701,12 @@ struct sk_buff *sk_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp)
skb = alloc_skb_fclone(size + sk->sk_prot->max_header, gfp);
if (skb) {
if (sk_wmem_schedule(sk, skb->truesize)) {
+ skb_reserve(skb, sk->sk_prot->max_header);
/*
* Make sure that we have exactly size bytes
* available to the caller, no more, no less.
*/
- skb_reserve(skb, skb_tailroom(skb) - size);
+ skb->avail_size = size;
return skb;
}
__kfree_skb(skb);
@@ -995,10 +996,9 @@ new_segment:
copy = seglen;
/* Where to copy to? */
- if (skb_tailroom(skb) > 0) {
+ if (skb_availroom(skb) > 0) {
/* We have some space in skb head. Superb! */
- if (copy > skb_tailroom(skb))
- copy = skb_tailroom(skb);
+ copy = min_t(int, copy, skb_availroom(skb));
err = skb_add_data_nocache(sk, skb, from, copy);
if (err)
goto do_fault;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 364784a..376b2cf 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2060,7 +2060,7 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *to,
/* Punt if not enough space exists in the first SKB for
* the data in the second
*/
- if (skb->len > skb_tailroom(to))
+ if (skb->len > skb_availroom(to))
break;
if (after(TCP_SKB_CB(skb)->end_seq, tcp_wnd_end(tp)))
^ permalink raw reply related
* linux-next: build failure after merge of the final tree (net-next tree related)
From: Stephen Rothwell @ 2012-04-10 5:29 UTC (permalink / raw)
To: David Miller, netdev
Cc: linux-next, linux-kernel, Mike Sinkovsky, Martin Schwidefsky,
Heiko Carstens
[-- Attachment #1: Type: text/plain, Size: 1058 bytes --]
Hi all,
After merging the final tree, today's linux-next build (s390 allmodconfig)
failed like this:
drivers/net/ethernet/wiznet/w5100.c: In function 'w5100_read_direct':
drivers/net/ethernet/wiznet/w5100.c:121:2: error: implicit declaration of function 'ioread8' [-Werror=implicit-function-declaration]
drivers/net/ethernet/wiznet/w5100.c: In function 'w5100_write_direct':
drivers/net/ethernet/wiznet/w5100.c:127:2: error: implicit declaration of function 'iowrite8' [-Werror=implicit-function-declaration]
drivers/net/ethernet/wiznet/w5100.c: In function 'w5100_read_indirect':
drivers/net/ethernet/wiznet/w5100.c:188:2: error: implicit declaration of function 'mmiowb' [-Werror=implicit-function-declaration]
drivers/net/ethernet/wiznet/w5100.c: In function 'w5100_hw_probe':
drivers/net/ethernet/wiznet/w5100.c:680:6: error: 'IRQ_TYPE_LEVEL_LOW' undeclared (first use in this function)
Caused by commit 8b1467a31343 ("Ethernet driver for the WIZnet W5100 chip").
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* RE: [PATCH] davinci_emac: Add cpu_freq support
From: Manjunathappa, Prakash @ 2012-04-10 5:16 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: netdev@vger.kernel.org,
davinci-linux-open-source@linux.davincidsp.com,
davem@davemloft.net
In-Reply-To: <4F82C830.1020100@mvista.com>
Hi Sergei,
On Mon, Apr 09, 2012 at 16:59:52, Sergei Shtylyov wrote:
> Hello.
>
> On 09-04-2012 14:49, Manjunathappa, Prakash wrote:
>
> > Reconfigure interrupt coalesce parameter for changed emac bus_freq
> > due to DVFS.
>
> > Signed-off-by: Manjunathappa, Prakash<prakash.pm@ti.com>
> > ---
> > drivers/net/ethernet/ti/davinci_emac.c | 60 ++++++++++++++++++++++++++++++++
> > 1 files changed, 60 insertions(+), 0 deletions(-)
>
> > diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
> > index 174a334..11d3bd7 100644
> > --- a/drivers/net/ethernet/ti/davinci_emac.c
> > +++ b/drivers/net/ethernet/ti/davinci_emac.c
> [...]
> > @@ -1761,6 +1765,46 @@ static const struct net_device_ops emac_netdev_ops = {
> > #endif
> > };
> >
> > +#ifdef CONFIG_CPU_FREQ
> > +static int davinci_emac_cpufreq_transition(struct notifier_block *nb,
> > + unsigned long val, void *data)
> > +{
> > + int ret = 0;
> > + struct emac_priv *priv;
> > +
> > + priv = container_of(nb, struct emac_priv, freq_transition);
> > + if (priv->coal_intvl != 0) {
> > + if (val == CPUFREQ_POSTCHANGE) {
> > + if (emac_bus_frequency != clk_get_rate(emac_clk)) {
>
> These 3 *if*s could be collapsed into one, and so indentation level
> lowered significantly.
>
Ok I will tie them with "&&".
> > + struct ethtool_coalesce coal;
> > +
> > + emac_bus_frequency = clk_get_rate(emac_clk);
> > +
> > + priv->bus_freq_mhz = (u32)(emac_bus_frequency /
> > + 1000000);
> > + coal.rx_coalesce_usecs = (priv->coal_intvl
> > + << 4);
> > + ret = emac_set_coalesce(priv->ndev,&coal);
> > + }
> > + }
> > + }
> > + return ret;
> > +}
> > +
> > +static inline int davinci_emac_cpufreq_register(struct emac_priv *priv)
> > +{
> > + priv->freq_transition.notifier_call = davinci_emac_cpufreq_transition;
> > + return cpufreq_register_notifier(&priv->freq_transition,
> > + CPUFREQ_TRANSITION_NOTIFIER);
> > +}
> > +
> > +static inline void davinci_emac_cpufreq_deregister(struct emac_priv *priv)
> > +{
> > + cpufreq_unregister_notifier(&priv->freq_transition,
> > + CPUFREQ_TRANSITION_NOTIFIER);
> > +}
> > +#endif
> > +
> > /**
> > * davinci_emac_probe: EMAC device probe
> > * @pdev: The DaVinci EMAC device that we are removing
> > @@ -1925,8 +1969,21 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev)
> > "(regs: %p, irq: %d)\n",
> > (void *)priv->emac_base_phys, ndev->irq);
> > }
> > +
> > +#ifdef CONFIG_CPU_FREQ
> > + rc = davinci_emac_cpufreq_register(priv);
> > + if (rc) {
> > + dev_err(&pdev->dev, "error in register_netdev\n");
>
> Really?
>
Ahh, my bad... I will fix this.
> > + rc = -ENODEV;
> > + goto cpufreq_reg_err;
> > + }
> > +#endif
> > return 0;
> >
> > +#ifdef CONFIG_CPU_FREQ
> > +cpufreq_reg_err:
> > + unregister_netdev(ndev);
> > +#endif
> > netdev_reg_err:
> > clk_disable(emac_clk);
> > no_irq_res:
> > @@ -1973,6 +2030,9 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev)
> >
> > release_mem_region(res->start, resource_size(res));
> >
> > +#ifdef CONFIG_CPU_FREQ
> > + davinci_emac_cpufreq_deregister(priv);
> > +#endif
>
> This is considered a bad practice to use #ifdef in the body of function.
> Define the faunction you call here as empty inline in case CONFIG_CPU_FREQ is
> not defined instead. The same about davinci_emac_cpufreq_register().
>
Ok. I will correct this as you suggested.
Thanks,
Prakash
> WBR, Sergei
>
^ permalink raw reply
* Re: 3.2.8/amd64 full interrupt hangs and deadlocks under big network copies (page allocation failure)
From: Marc MERLIN @ 2012-04-10 5:11 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, Larry.Finger, bhutchings, linux-wireless, netdev
In-Reply-To: <1334030180.13293.98.camel@edumazet-glaptop>
On Tue, Apr 10, 2012 at 05:56:20AM +0200, Eric Dumazet wrote:
> > What wireless device are we dealing with again?
>
> Problem seems related to tailroom needed by mac80211
> (IEEE80211_ENCRYPT_TAILROOM = 18 bytes)
>
> So we must reallocate skb->head, thats impressive nobody cares.
>
> [ 3007.249687] ieee80211_skb_resize(skb=ffff8802329846e8) cloned=1 head_need=0 tail_need=18 skb->len=1494 ksize=4096 tailroom=0 headroom=2282
> [ 3007.249693] ieee80211_skb_resize(skb=ffff8802329846e8) cloned=0 head_need=0 tail_need=0 skb->len=1526 ksize=8192 tailroom=64 headroom=2250
>
> Ouch... skb_tailroom() seems wrong ... it seems pskb_expand_head() is really suboptimal.
>
> It appears tcp_sendmsg() tries to fill skb completely, with no available tailroom :
>
> if (skb_tailroom(skb) > 0) {
> /* We have some space in skb head. Superb! */
> if (copy > skb_tailroom(skb))
> copy = skb_tailroom(skb);
> err = skb_add_data_nocache(sk, skb, from, copy);
> if (err)
> goto do_fault;
> } else {
>
> Shouldnt we take into account dev->needed_tailroom ?
>
> I'll submit a pskb_expand_head() fix asap.
Thanks for finding this.
To answer an earlier question, I tried the non wireless case too.
The problem is harder to reproduce over e1000e though, I just got two short
hangs where my mouse cursor was hung for 5-10 seconds, but nothing in
syslog/dmesg this time.
I'm pretty sure this older log below did happen on e1000e with wireless disabled
though (but it had a taint 'O'):
If that helps, my earlier message had the traces below.
I can report back when you have a patch you'd like me to try out.
Thanks again,
Marc
> [28451.191115] WorkerPool/1248 D ffff88013bc93580 0 12483 3740 0x00000080
> [28451.191115] ffff8801189ba100 0000000000000082 0000000000000000 ffff880134f2e180
> [28451.191115] 0000000000013580 ffff88001614bfd8 ffff88001614bfd8 ffff8801189ba100
> [28451.191115] ffffffff811b4b62 000000010164525a 0000000000000046 ffffffff8165a250
> [28451.191115] Call Trace:
> [28451.191115] [<ffffffff811b4b62>] ? sha_transform+0x395/0x1209
> [28451.191115] [<ffffffff8134a9b4>] ? __mutex_lock_common.isra.6+0x13d/0x219
> [28451.191115] [<ffffffff81242714>] ? extract_buf+0x86/0xf2
> [28451.191115] [<ffffffff8134a7e6>] ? mutex_lock+0xf/0x1f
> [28451.191115] [<ffffffff81298979>] ? rtnetlink_rcv+0xe/0x28
> [28451.191115] [<ffffffff812ad007>] ? netlink_unicast+0xe6/0x14e
> [28451.191115] [<ffffffff812ad26b>] ? netlink_sendmsg+0x1fc/0x237
> [28451.191115] [<ffffffff8127c770>] ? sock_sendmsg+0xc1/0xde
> [28451.191115] [<ffffffff810eca23>] ? __cache_free.isra.40+0x19/0x1a7
> [28451.191115] [<ffffffff813496be>] ? nl_pid_hash_rehash+0xc8/0xef
> [28451.191115] [<ffffffff8103e0fa>] ? get_parent_ip+0x9/0x1b
> [28451.191115] [<ffffffff8103e0fa>] ? get_parent_ip+0x9/0x1b
> [28451.191115] [<ffffffff8134e1d2>] ? sub_preempt_count+0x83/0x94
> [28451.191115] [<ffffffff810fd81e>] ? fget_light+0x85/0x8d
> [28451.191115] [<ffffffff8127e0e3>] ? sys_sendto+0xf7/0x137
> [28451.191115] [<ffffffff8103e0fa>] ? get_parent_ip+0x9/0x1b
> [28451.191115] [<ffffffff8134e1d2>] ? sub_preempt_count+0x83/0x94
> [28451.191115] [<ffffffff8134b725>] ? _raw_spin_unlock+0x24/0x30
> [28451.191115] [<ffffffff8108d73e>] ? audit_syscall_entry+0x105/0x130
> [28451.191115] [<ffffffff8134fd52>] ? system_call_fastpath+0x16/0x1b
>
>
>
> Below are lines I got in syslog during the copy.
> Highlight is:
> [ 4437.367046] kworker/1:1: page allocation failure: order:1, mode:0x20
> and then:
> [ 8640.516177] INFO: task flush-0:37:7122 blocked for more than 120 seconds.
> and then 120,000 lines(!) of:
> [ 9654.042164] ieee80211 phy0: failed to reallocate TX buffer
>
> unedited lines below.
>
> So, any idea of what I can try next?
>
> Thanks,
> Marc
>
>
> [ 4437.367046] kworker/1:1: page allocation failure: order:1, mode:0x20
> [ 4437.367053] Pid: 8067, comm: kworker/1:1 Tainted: G O 3.2.8-amd64-volpreempt-noide-20120208 #1
> [ 4437.367056] Call Trace:
> [ 4437.367058] <IRQ> [<ffffffff810b9ec0>] ? warn_alloc_failed+0x11f/0x132
> [ 4437.367074] [<ffffffff810bcdaa>] ? __alloc_pages_nodemask+0x6b1/0x72f
> [ 4437.367081] [<ffffffff810ec911>] ? kmem_getpages+0x4c/0xd9
> [ 4437.367086] [<ffffffff810ec911>] ? kmem_getpages+0x4c/0xd9
> [ 4437.367090] [<ffffffff810edd21>] ? fallback_alloc+0x123/0x1c2
> [ 4437.367096] [<ffffffff812846db>] ? pskb_expand_head+0xe0/0x24a
> [ 4437.367101] [<ffffffff810ee215>] ? __kmalloc+0xb2/0x10a
> [ 4437.367105] [<ffffffff812846db>] ? pskb_expand_head+0xe0/0x24a
> [ 4437.367139] [<ffffffffa03e22c1>] ? ieee80211_skb_resize+0x64/0x9d [mac80211]
> [ 4437.367154] [<ffffffffa03e4252>] ? ieee80211_subif_start_xmit+0x705/0x883 [mac80211]
> [ 4437.367175] [<ffffffff8128e767>] ? dev_hard_start_xmit+0x40b/0x552
> [ 4437.367179] [<ffffffff812a4adc>] ? sch_direct_xmit+0x63/0x13a
> [ 4437.367182] [<ffffffff8128eb8e>] ? dev_queue_xmit+0x2e0/0x4b5
> [ 4437.367185] [<ffffffff812b764d>] ? ip_finish_output2+0x1c7/0x218
> [ 4437.367188] [<ffffffff812b86aa>] ? __ip_flush_pending_frames.isra.29+0x69/0x69
> [ 4437.367191] [<ffffffff812b8a6a>] ? ip_queue_xmit+0x2cd/0x30d
> [ 4437.367195] [<ffffffff81066be9>] ? getnstimeofday+0x4a/0x7b
> [ 4437.367198] [<ffffffff812ca1d2>] ? tcp_transmit_skb+0x6d7/0x70a
> [ 4437.367201] [<ffffffff812cac5f>] ? tcp_write_xmit+0x698/0x7a1
> [ 4437.367204] [<ffffffff812c77bf>] ? tcp_ack+0x14e3/0x1658
> [ 4437.367207] [<ffffffff812c89bd>] ? tcp_established_options+0x2b/0x9e
> [ 4437.367210] [<ffffffff812cada9>] ? __tcp_push_pending_frames+0x18/0x44
> [ 4437.367213] [<ffffffff812c4e27>] ? tcp_data_snd_check+0x2c/0xfd
> [ 4437.367216] [<ffffffff812c86c5>] ? tcp_rcv_established+0x4f0/0x549
> [ 4437.367220] [<ffffffff8103ec39>] ? select_task_rq_fair+0x67b/0x690
> [ 4437.367223] [<ffffffff812ce735>] ? tcp_v4_do_rcv+0x166/0x323
> [ 4437.367226] [<ffffffff812cfdce>] ? tcp_v4_rcv+0x404/0x65d
> [ 4437.367230] [<ffffffff812b4d55>] ? ip_local_deliver_finish+0x148/0x1ba
> [ 4437.367233] [<ffffffff8128cfa4>] ? __netif_receive_skb+0x3f2/0x43f
> [ 4437.367236] [<ffffffff8128d31d>] ? netif_receive_skb+0x7e/0x84
> [ 4437.367239] [<ffffffff8128d7dd>] ? napi_gro_receive+0x1c/0x29
> [ 4437.367241] [<ffffffff8128d398>] ? napi_skb_finish+0x1c/0x31
> [ 4437.367253] [<ffffffffa026bde3>] ? e1000_clean_rx_irq+0x1f3/0x290 [e1000e]
> [ 4437.367261] [<ffffffffa026c26c>] ? e1000_clean+0x69/0x208 [e1000e]
> [ 4437.367264] [<ffffffff8128d8fb>] ? net_rx_action+0xa4/0x1c0
> [ 4437.367268] [<ffffffff8104c581>] ? __do_softirq+0xc0/0x188
> [ 4437.367272] [<ffffffff81351fac>] ? call_softirq+0x1c/0x30
> [ 4437.367276] [<ffffffff8100f98d>] ? do_softirq+0x3c/0x7b
> [ 4437.367278] [<ffffffff8104c87c>] ? irq_exit+0x3d/0xa7
> [ 4437.367281] [<ffffffff8100f6b4>] ? do_IRQ+0x81/0x97
> [ 4437.367285] [<ffffffff8134ba2e>] ? common_interrupt+0x6e/0x6e
> [ 4437.367287] <EOI> [<ffffffffa008b32c>] ? dec128+0x434/0x80c [aes_x86_64]
> [ 4437.367307] [<ffffffffa0085164>] ? crypt+0xae/0x101 [xts]
> [ 4437.367313] [<ffffffffa008b712>] ? aes_decrypt+0xe/0xe [aes_x86_64]
> [ 4437.367320] [<ffffffffa008b704>] ? dec128+0x80c/0x80c [aes_x86_64]
> [ 4437.367327] [<ffffffffa00851f6>] ? decrypt+0x3f/0x44 [xts]
> [ 4437.367331] [<ffffffff8118cdb3>] ? async_decrypt+0x37/0x3c
> [ 4437.367338] [<ffffffffa0105e2a>] ? crypt_convert+0x22f/0x2c4 [dm_crypt]
> [ 4437.367342] [<ffffffff8100d02f>] ? load_TLS+0x7/0xa
> [ 4437.367348] [<ffffffffa01061b8>] ? kcryptd_crypt+0x56/0x342 [dm_crypt]
> [ 4437.367352] [<ffffffff81038cd2>] ? finish_task_switch+0x86/0xb7
> [ 4437.367355] [<ffffffff8103e0fa>] ? get_parent_ip+0x9/0x1b
> [ 4437.367358] [<ffffffff8134e1d2>] ? sub_preempt_count+0x83/0x94
> [ 4437.367361] [<ffffffff8103612b>] ? need_resched+0x1a/0x23
> [ 4437.367368] [<ffffffffa0106162>] ? crypt_convert_init.isra.14+0x4f/0x4f [dm_crypt]
> [ 4437.367372] [<ffffffff8105b867>] ? process_one_work+0x16d/0x298
> [ 4437.367375] [<ffffffff8105c84a>] ? worker_thread+0xc2/0x145
> [ 4437.367378] [<ffffffff8105c788>] ? manage_workers.isra.23+0x15b/0x15b
> [ 4437.367381] [<ffffffff8105f9fe>] ? kthread+0x76/0x7e
> [ 4437.367384] [<ffffffff81351eb4>] ? kernel_thread_helper+0x4/0x10
> [ 4437.367387] [<ffffffff8105f988>] ? kthread_worker_fn+0x139/0x139
> [ 4437.367390] [<ffffffff81351eb0>] ? gs_change+0x13/0x13
> [ 4437.367392] Mem-Info:
> [ 4437.367393] Node 0 DMA per-cpu:
> [ 4437.367396] CPU 0: hi: 0, btch: 1 usd: 0
> [ 4437.367397] CPU 1: hi: 0, btch: 1 usd: 0
> [ 4437.367399] Node 0 DMA32 per-cpu:
> [ 4437.367401] CPU 0: hi: 186, btch: 31 usd: 164
> [ 4437.367403] CPU 1: hi: 186, btch: 31 usd: 111
> [ 4437.367405] Node 0 Normal per-cpu:
> [ 4437.367407] CPU 0: hi: 186, btch: 31 usd: 114
> [ 4437.367409] CPU 1: hi: 186, btch: 31 usd: 158
> [ 4437.367413] active_anon:391300 inactive_anon:132951 isolated_anon:0
> [ 4437.367414] active_file:136666 inactive_file:140710 isolated_file:31
> [ 4437.367415] unevictable:1 dirty:3402 writeback:26688 unstable:7844
> [ 4437.367416] free:36509 slab_reclaimable:85289 slab_unreclaimable:35524
> [ 4437.367417] mapped:18088 shmem:35934 pagetables:9300 bounce:0
> [ 4437.367419] Node 0 DMA free:15712kB min:260kB low:324kB high:388kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:36kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15684kB mlocked:0kB dirty:0kB writeback:36kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:160kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:40833 all_unreclaimable? yes
> [ 4437.367428] lowmem_reserve[]: 0 2960 3907 3907
> [ 4437.367432] Node 0 DMA32 free:110732kB min:51004kB low:63752kB high:76504kB active_anon:1380396kB inactive_anon:345140kB active_file:422008kB inactive_file:437440kB unevictable:4kB isolated(anon):0kB isolated(file):124kB present:3031688kB mlocked:4kB dirty:7148kB writeback:72004kB mapped:39424kB shmem:64836kB slab_reclaimable:212408kB slab_unreclaimable:80516kB kernel_stack:1720kB pagetables:19252kB unstable:23964kB bounce:0kB writeback_tmp:0kB pages_scanned:63 all_unreclaimable? no
> [ 4437.367442] lowmem_reserve[]: 0 0 946 946
> [ 4437.367445] Node 0 Normal free:19592kB min:16312kB low:20388kB high:24468kB active_anon:184804kB inactive_anon:186664kB active_file:124656kB inactive_file:125364kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:969600kB mlocked:0kB dirty:6460kB writeback:34712kB mapped:32928kB shmem:78900kB slab_reclaimable:128748kB slab_unreclaimable:61420kB kernel_stack:2792kB pagetables:17948kB unstable:7412kB bounce:0kB writeback_tmp:0kB pages_scanned:89 all_unreclaimable? no
> [ 4437.367455] lowmem_reserve[]: 0 0 0 0
> [ 4437.367458] Node 0 DMA: 2*4kB 1*8kB 1*16kB 0*32kB 1*64kB 2*128kB 2*256kB 1*512kB 2*1024kB 2*2048kB 2*4096kB = 15712kB
> [ 4437.367467] Node 0 DMA32: 25961*4kB 73*8kB 8*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 1*2048kB 1*4096kB = 110732kB
> [ 4437.367475] Node 0 Normal: 4134*4kB 0*8kB 1*16kB 1*32kB 0*64kB 2*128kB 1*256kB 1*512kB 0*1024kB 1*2048kB 0*4096kB = 19656kB
> [ 4437.367484] 317456 total pagecache pages
> [ 4437.367485] 4042 pages in swap cache
> [ 4437.367487] Swap cache stats: add 31786, delete 27744, find 10282/11070
> [ 4437.367489] Free swap = 4012560kB
> [ 4437.367490] Total swap = 4106248kB
> [ 4437.370978] 1032176 pages RAM
> [ 4437.370978] 42834 pages reserved
> [ 4437.370978] 390787 pages shared
> [ 4437.370978] 750687 pages non-shared
>
>
> [ 8640.516177] INFO: task flush-0:37:7122 blocked for more than 120 seconds.
> [ 8640.516182] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [ 8640.516186] flush-0:37 D ffff88013bc93580 0 7122 2 0x00000080
> [ 8640.516192] ffff880072c28810 0000000000000046 ffff880100000000 ffff880134f2e180
> [ 8640.516199] 0000000000013580 ffff88006d491fd8 ffff88006d491fd8 ffff880072c28810
> [ 8640.516205] ffff88013bfd1c50 000000018134b58b ffff88010c3cc1b0 ffff88006d491d18
> [ 8640.516211] Call Trace:
> [ 8640.516221] [<ffffffff8110e81a>] ? inode_owner_or_capable+0x36/0x36
> [ 8640.516226] [<ffffffff8110e820>] ? inode_wait+0x6/0xa
> [ 8640.516232] [<ffffffff8134a72c>] ? __wait_on_bit+0x3e/0x71
> [ 8640.516241] [<ffffffff8103e0fa>] ? get_parent_ip+0x9/0x1b
> [ 8640.516245] [<ffffffff81119674>] ? inode_wait_for_writeback+0xa2/0xc8
> [ 8640.516249] [<ffffffff810600c9>] ? autoremove_wake_function+0x2a/0x2a
> [ 8640.516252] [<ffffffff8111b4b4>] ? wb_writeback+0x226/0x255
> [ 8640.516255] [<ffffffff8134e27d>] ? add_preempt_count+0x9a/0x9c
> [ 8640.516258] [<ffffffff8111b8d4>] ? wb_do_writeback+0x150/0x1b2
> [ 8640.516261] [<ffffffff8111b9c5>] ? bdi_writeback_thread+0x8f/0x204
> [ 8640.516264] [<ffffffff8111b936>] ? wb_do_writeback+0x1b2/0x1b2
> [ 8640.516266] [<ffffffff8105f9fe>] ? kthread+0x76/0x7e
> [ 8640.516270] [<ffffffff81351eb4>] ? kernel_thread_helper+0x4/0x10
> [ 8640.516273] [<ffffffff8105f988>] ? kthread_worker_fn+0x139/0x139
> [ 8640.516275] [<ffffffff81351eb0>] ? gs_change+0x13/0x13
> [ 8640.516281] INFO: task cp:7568 blocked for more than 120 seconds.
> [ 8640.516283] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
> [ 8640.516284] cp D ffff88013bc13580 0 7568 6744 0x00000080
> [ 8640.516288] ffff880123976750 0000000000000082 0000000000000000 ffffffff8160d020
> [ 8640.516292] 0000000000013580 ffff88001b3a9fd8 ffff88001b3a9fd8 ffff880123976750
> [ 8640.516295] 0000000000000001 0000000181066767 ffff880131463e50 ffff88013bc13e08
> [ 8640.516299] Call Trace:
> [ 8640.516303] [<ffffffff810b5d03>] ? __lock_page+0x66/0x66
> [ 8640.516306] [<ffffffff8134a2ec>] ? io_schedule+0x58/0x6f
> [ 8640.516308] [<ffffffff810b5d09>] ? sleep_on_page+0x6/0xa
> [ 8640.516311] [<ffffffff8134a72c>] ? __wait_on_bit+0x3e/0x71
> [ 8640.516313] [<ffffffff810b5e51>] ? wait_on_page_bit+0x6e/0x73
> [ 8640.516316] [<ffffffff810600c9>] ? autoremove_wake_function+0x2a/0x2a
> [ 8640.516319] [<ffffffff810b5f29>] ? filemap_fdatawait_range+0x74/0x139
> [ 8640.516327] [<ffffffff8111acab>] ? writeback_single_inode+0x155/0x2f4
> [ 8640.516330] [<ffffffff8111ae94>] ? sync_inode+0x4a/0x6f
> [ 8640.516343] [<ffffffffa06b9b02>] ? nfs_wb_all+0x39/0x3e [nfs]
> [ 8640.516351] [<ffffffffa06aeed1>] ? nfs_setattr+0x8e/0xf6 [nfs]
> [ 8640.516354] [<ffffffff811104c3>] ? notify_change+0x177/0x24f
> [ 8640.516357] [<ffffffff8111e85c>] ? utimes_common+0x10c/0x135
> [ 8640.516361] [<ffffffff810fd55a>] ? fget+0x50/0x57
> [ 8640.516364] [<ffffffff8111e90f>] ? do_utimes+0x8a/0xd6
> [ 8640.516367] [<ffffffff810fc7a2>] ? vfs_read+0x9f/0xe6
> [ 8640.516369] [<ffffffff8111ea24>] ? sys_utimensat+0x64/0x6b
> [ 8640.516372] [<ffffffff8134fd52>] ? system_call_fastpath+0x16/0x1b
>
>
> [ 9654.042164] ieee80211 phy0: failed to reallocate TX buffer
> [ 9654.042189] ieee80211 phy0: failed to reallocate TX buffer
> (120,000 lines of this)
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/
^ permalink raw reply
* [PATCH] gianfar: add missing include
From: Michael Neuling @ 2012-04-10 4:18 UTC (permalink / raw)
To: David S. Miller, Richard Cochran; +Cc: linuxppc-dev, netdev, linux-next
next-20120405 compiled with mpc85xx_defconfig gives the following:
CC drivers/net/ethernet/freescale/gianfar_ethtool.o
drivers/net/ethernet/freescale/gianfar_ethtool.c: In function 'gfar_get_ts_info':
drivers/net/ethernet/freescale/gianfar_ethtool.c:1751:4: error: 'SOF_TIMESTAMPING_RX_SOFTWARE' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1751:4: note: each undeclared identifier is reported only once for each function it appears in
drivers/net/ethernet/freescale/gianfar_ethtool.c:1752:4: error: 'SOF_TIMESTAMPING_SOFTWARE' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1757:3: error: 'SOF_TIMESTAMPING_TX_HARDWARE' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1758:3: error: 'SOF_TIMESTAMPING_RX_HARDWARE' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1759:3: error: 'SOF_TIMESTAMPING_RAW_HARDWARE' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1762:9: error: 'HWTSTAMP_TX_OFF' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1763:9: error: 'HWTSTAMP_TX_ON' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1765:9: error: 'HWTSTAMP_FILTER_NONE' undeclared (first use in this function)
drivers/net/ethernet/freescale/gianfar_ethtool.c:1766:9: error: 'HWTSTAMP_FILTER_ALL' undeclared (first use in this function)
This is because of a missing include file from:
6663628 gianfar: Support the get_ts_info ethtool method.
Signed-off-by: Michael Neuling <mikey@neuling.org>
CC: Richard Cochran <richardcochran@gmail.com>
CC: David S. Miller <davem@davemloft.net>
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
index 27f49c7..3c34b32b 100644
--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
+++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
@@ -29,6 +29,7 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
+#include <linux/net_tstamp.h>
#include <asm/io.h>
#include <asm/irq.h>
^ permalink raw reply related
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: KAMEZAWA Hiroyuki @ 2012-04-10 4:15 UTC (permalink / raw)
To: Glauber Costa; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F83A29D.1060402@parallels.com>
(2012/04/10 12:01), Glauber Costa wrote:
> On 04/09/2012 11:51 PM, Glauber Costa wrote:
>> On 04/09/2012 11:37 PM, KAMEZAWA Hiroyuki wrote:
>>> Hm. What happens in following sequence ?
>>>
>>> 1. a memcg is created
>>> 2. put a task into the memcg, start tcp steam
>>> 3. set tcp memory limit
>>>
>>> The resource used between 2 and 3 will cause the problem finally.
>>
>> I don't get it. if a task is in memcg, but no limit is set,
>> that socket will be assigned null memcg, and will stay like that
>> forever. Only new sockets will have the new memcg pointer.
>>
>> And previously, we could have the memcg pointer alive, but the jump
>> labels to be disabled. With the patch I posted, this can't happen
>> anymore, since the jump labels are guaranteed to live throughout the
>> whole socket life.
>>
>>> Then, Dave's request
>>> ==
>>> You must either:
>>>
>>> 1) Integrate the socket's existing usage when the limit is set.
>>>
>>> 2) Avoid accounting completely for a socket that started before
>>> the limit was set.
>>> ==
>>> are not satisfied. So, we need to have a state per sockets, it's accounted
>>> or not. I'll look into this problem again, today.
>>>
>>
>> Of course they are.
>>
>> Every socket created before we set the limit is not accounted.
>> This is 2) that Dave mentioned, and it was *always* this way.
>>
>> The problem here was the opposite: You could disable the jump labels
>> with sockets still in flight, because we were disabling it based on
>> the limit being set back to unlimited.
>>
>> What this patch does, is defer that until the last socket limited dies.
>>
>
> Okay, there is an additional thing to be considered here:
>
> Due to the nature of how jump label works, once they are enabled for one
> of the cgroups, they will be enabled for all of them. So the patch I
> sent may still break in some scenarios because of the way we record that
> the limit was set.
>
> However, if my theory behind what is causing the problem is correct,
> this patch should fix the issue for you.
Now, our issue is leak of accounting, regardless of warning.
> Let me know if it does, and
> I'll work on the final solution.
>
The problem is that jump_label updating is not atomic_ops.
I'm _not_ sure the update order of the jump_label in sock_update_memcg()
and other jump instructions inserted at accounting.
For example, if the jump instruction in sock_update_memcg() is updated 1st
and others are updated later, it's unclear whether sockets which has _valid_
sock->sk_cgrp will be accounted or not because accounting jump instruction
may not be updated yet.
Hopefully, label in sock_update_memcg should be updated last...
Hm. If I do, I'll add one more key as:
atomic_t sock_should_memcg_aware;
And update 2 keys in following order.
At enable
static_key_slow_inc(&memcg_socket_limit_enabled)
atomic_inc(&sock_should_memcg_aware);
At disable
atomic_dec(&sock_should_memcg_aware);
static_key_slow_dec(&memcg_socket_limit_enabled)
And
==
void sock_update_memcg(struct sock *sk)
{
if (atomic_read(&sock_should_memcg_aware)) {
==
Thanks,
-Kame
^ permalink raw reply
* Re: 3.2.8/amd64 full interrupt hangs and deadlocks under big network copies (page allocation failure)
From: Eric Dumazet @ 2012-04-10 3:56 UTC (permalink / raw)
To: David Miller; +Cc: Larry.Finger, marc, bhutchings, linux-wireless, netdev
In-Reply-To: <20120409.153452.1284163346306246866.davem@davemloft.net>
On Mon, 2012-04-09 at 15:34 -0400, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Mon, 09 Apr 2012 21:11:12 +0200
>
> > I think Marc posted stack traces showing problem on transmit side.
> ...
> > I dont really understand how it can happen, with MTU=1500
>
> Depending upon the configuration and the driver, wireless can need
> more headroom. For encryption an extra 8 bytes are necessary, and the
> driver may request a variable amount of extra headroom via
> ->hw.extra_tx_headroom
>
> What wireless device are we dealing with again?
Problem seems related to tailroom needed by mac80211
(IEEE80211_ENCRYPT_TAILROOM = 18 bytes)
So we must reallocate skb->head, thats impressive nobody cares.
[ 3007.249687] ieee80211_skb_resize(skb=ffff8802329846e8) cloned=1 head_need=0 tail_need=18 skb->len=1494 ksize=4096 tailroom=0 headroom=2282
[ 3007.249693] ieee80211_skb_resize(skb=ffff8802329846e8) cloned=0 head_need=0 tail_need=0 skb->len=1526 ksize=8192 tailroom=64 headroom=2250
Ouch... skb_tailroom() seems wrong ... it seems pskb_expand_head() is really suboptimal.
It appears tcp_sendmsg() tries to fill skb completely, with no available tailroom :
if (skb_tailroom(skb) > 0) {
/* We have some space in skb head. Superb! */
if (copy > skb_tailroom(skb))
copy = skb_tailroom(skb);
err = skb_add_data_nocache(sk, skb, from, copy);
if (err)
goto do_fault;
} else {
Shouldnt we take into account dev->needed_tailroom ?
I'll submit a pskb_expand_head() fix asap.
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: KAMEZAWA Hiroyuki @ 2012-04-10 3:21 UTC (permalink / raw)
To: Glauber Costa; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F83A022.1000701@parallels.com>
(2012/04/10 11:51), Glauber Costa wrote:
> On 04/09/2012 11:37 PM, KAMEZAWA Hiroyuki wrote:
>> Hm. What happens in following sequence ?
>>
>> 1. a memcg is created
>> 2. put a task into the memcg, start tcp steam
>> 3. set tcp memory limit
>>
>> The resource used between 2 and 3 will cause the problem finally.
>
> I don't get it. if a task is in memcg, but no limit is set,
> that socket will be assigned null memcg, and will stay like that
> forever. Only new sockets will have the new memcg pointer.
>
> And previously, we could have the memcg pointer alive, but the jump
> labels to be disabled. With the patch I posted, this can't happen
> anymore, since the jump labels are guaranteed to live throughout the
> whole socket life.
>
>> Then, Dave's request
>> ==
>> You must either:
>>
>> 1) Integrate the socket's existing usage when the limit is set.
>>
>> 2) Avoid accounting completely for a socket that started before
>> the limit was set.
>> ==
>> are not satisfied. So, we need to have a state per sockets, it's accounted
>> or not. I'll look into this problem again, today.
>>
>
> Of course they are.
>
> Every socket created before we set the limit is not accounted.
> This is 2) that Dave mentioned, and it was *always* this way.
>
> The problem here was the opposite: You could disable the jump labels
> with sockets still in flight, because we were disabling it based on
> the limit being set back to unlimited.
>
> What this patch does, is defer that until the last socket limited dies.
>
Thank you for explanation. Hmm, sk->cgrp check ?
Ah, yes it's updated by sock_update_memcg() under jump_label, which is
called by tcp_v4_init_sock().
Hm. and jump_label()'s atomic counter and mutex_lock will be a guard against
set/unset race. Ok.
BTW, what will happen in following case ?
Assume that the last memcg is destroyed and call jump_label_dec. And the
thread waits for jump_label_mutex for a while.
CPU A CPU B
jump_label_dec() # mutex will be held sock_update_memcg() is called
sk_cgrp is set.
...modify instructions some accounting is done.
mutex_unlock()
I wonder you need some serialization somewhere OR disallow turning off accounting.
Thanks,
-Kame
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: Glauber Costa @ 2012-04-10 3:01 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F83A022.1000701@parallels.com>
On 04/09/2012 11:51 PM, Glauber Costa wrote:
> On 04/09/2012 11:37 PM, KAMEZAWA Hiroyuki wrote:
>> Hm. What happens in following sequence ?
>>
>> 1. a memcg is created
>> 2. put a task into the memcg, start tcp steam
>> 3. set tcp memory limit
>>
>> The resource used between 2 and 3 will cause the problem finally.
>
> I don't get it. if a task is in memcg, but no limit is set,
> that socket will be assigned null memcg, and will stay like that
> forever. Only new sockets will have the new memcg pointer.
>
> And previously, we could have the memcg pointer alive, but the jump
> labels to be disabled. With the patch I posted, this can't happen
> anymore, since the jump labels are guaranteed to live throughout the
> whole socket life.
>
>> Then, Dave's request
>> ==
>> You must either:
>>
>> 1) Integrate the socket's existing usage when the limit is set.
>>
>> 2) Avoid accounting completely for a socket that started before
>> the limit was set.
>> ==
>> are not satisfied. So, we need to have a state per sockets, it's accounted
>> or not. I'll look into this problem again, today.
>>
>
> Of course they are.
>
> Every socket created before we set the limit is not accounted.
> This is 2) that Dave mentioned, and it was *always* this way.
>
> The problem here was the opposite: You could disable the jump labels
> with sockets still in flight, because we were disabling it based on
> the limit being set back to unlimited.
>
> What this patch does, is defer that until the last socket limited dies.
>
Okay, there is an additional thing to be considered here:
Due to the nature of how jump label works, once they are enabled for one
of the cgroups, they will be enabled for all of them. So the patch I
sent may still break in some scenarios because of the way we record that
the limit was set.
However, if my theory behind what is causing the problem is correct,
this patch should fix the issue for you. Let me know if it does, and
I'll work on the final solution.
^ permalink raw reply
* [PATCH 2/2] tools: virtio: add a top-like utility for displaying vhost satistics
From: Jason Wang @ 2012-04-10 2:58 UTC (permalink / raw)
To: netdev, virtualization, linux-kernel, kvm, mst
In-Reply-To: <20120410025327.49693.93562.stgit@amd-6168-8-1.englab.nay.redhat.com>
This patch adds simple python to display vhost satistics of vhost, the codes
were based on kvm_stat script from qemu. As work function has been recored,
filters could be used to distinguish which kinds of work are being executed or
queued:
vhost statistics
vhost_virtio_get_vq_desc 1460997 219682
vhost_work_execute_start 101248 12842
vhost_work_execute_end 101247 12842
vhost_work_queue_wakeup 101263 12841
vhost_virtio_signal 68452 8659
vhost_work_queue_wakeup(rx_net) 51797 6584
vhost_work_execute_start(rx_net) 51795 6584
vhost_work_queue_coalesce 35737 6571
vhost_work_queue_coalesce(rx_net) 35709 6566
vhost_virtio_update_avail_event 49512 6271
vhost_work_execute_start(tx_kick) 49429 6254
vhost_work_queue_wakeup(tx_kick) 49442 6252
vhost_work_queue_coalesce(tx_kick) 28 5
vhost_work_execute_start(rx_kick) 22 3
vhost_work_queue_wakeup(rx_kick) 22 3
vhost_poll_start 4 0
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
tools/virtio/vhost_stat | 360 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 360 insertions(+), 0 deletions(-)
create mode 100755 tools/virtio/vhost_stat
diff --git a/tools/virtio/vhost_stat b/tools/virtio/vhost_stat
new file mode 100755
index 0000000..b730f3b
--- /dev/null
+++ b/tools/virtio/vhost_stat
@@ -0,0 +1,360 @@
+#!/usr/bin/python
+#
+# top-like utility for displaying vhost statistics
+#
+# Copyright 2012 Red Hat, Inc.
+#
+# Modified from kvm_stat from qemu
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+
+import curses
+import sys, os, time, optparse
+
+work_types = {
+ "handle_rx_kick" : "rx_kick",
+ "handle_tx_kick" : "tx_kick",
+ "handle_rx_net" : "rx_net",
+ "handle_tx_net" : "tx_net",
+ "vhost_attach_cgroups_work": "cg_attach"
+ }
+
+addr = {}
+
+kallsyms = file("/proc/kallsyms").readlines()
+for kallsym in kallsyms:
+ entry = kallsym.split()
+ if entry[2] in work_types.keys():
+ addr["0x%s" % entry[0]] = work_types[entry[2]]
+
+filters = {
+ 'vhost_work_queue_wakeup': ('function', addr),
+ 'vhost_work_queue_coalesce' : ('function', addr),
+ 'vhost_work_execute_start' : ('function', addr),
+ 'vhost_poll_start' : ('function', addr),
+ 'vhost_poll_stop' : ('function', addr),
+}
+
+def invert(d):
+ return dict((x[1], x[0]) for x in d.iteritems())
+
+for f in filters:
+ filters[f] = (filters[f][0], invert(filters[f][1]))
+
+import ctypes, struct, array
+
+libc = ctypes.CDLL('libc.so.6')
+syscall = libc.syscall
+class perf_event_attr(ctypes.Structure):
+ _fields_ = [('type', ctypes.c_uint32),
+ ('size', ctypes.c_uint32),
+ ('config', ctypes.c_uint64),
+ ('sample_freq', ctypes.c_uint64),
+ ('sample_type', ctypes.c_uint64),
+ ('read_format', ctypes.c_uint64),
+ ('flags', ctypes.c_uint64),
+ ('wakeup_events', ctypes.c_uint32),
+ ('bp_type', ctypes.c_uint32),
+ ('bp_addr', ctypes.c_uint64),
+ ('bp_len', ctypes.c_uint64),
+ ]
+def _perf_event_open(attr, pid, cpu, group_fd, flags):
+ return syscall(298, ctypes.pointer(attr), ctypes.c_int(pid),
+ ctypes.c_int(cpu), ctypes.c_int(group_fd),
+ ctypes.c_long(flags))
+
+PERF_TYPE_HARDWARE = 0
+PERF_TYPE_SOFTWARE = 1
+PERF_TYPE_TRACEPOINT = 2
+PERF_TYPE_HW_CACHE = 3
+PERF_TYPE_RAW = 4
+PERF_TYPE_BREAKPOINT = 5
+
+PERF_SAMPLE_IP = 1 << 0
+PERF_SAMPLE_TID = 1 << 1
+PERF_SAMPLE_TIME = 1 << 2
+PERF_SAMPLE_ADDR = 1 << 3
+PERF_SAMPLE_READ = 1 << 4
+PERF_SAMPLE_CALLCHAIN = 1 << 5
+PERF_SAMPLE_ID = 1 << 6
+PERF_SAMPLE_CPU = 1 << 7
+PERF_SAMPLE_PERIOD = 1 << 8
+PERF_SAMPLE_STREAM_ID = 1 << 9
+PERF_SAMPLE_RAW = 1 << 10
+
+PERF_FORMAT_TOTAL_TIME_ENABLED = 1 << 0
+PERF_FORMAT_TOTAL_TIME_RUNNING = 1 << 1
+PERF_FORMAT_ID = 1 << 2
+PERF_FORMAT_GROUP = 1 << 3
+
+import re
+
+sys_tracing = '/sys/kernel/debug/tracing'
+
+class Group(object):
+ def __init__(self, cpu):
+ self.events = []
+ self.group_leader = None
+ self.cpu = cpu
+ def add_event(self, name, event_set, tracepoint, filter = None):
+ self.events.append(Event(group = self,
+ name = name, event_set = event_set,
+ tracepoint = tracepoint, filter = filter))
+ if len(self.events) == 1:
+ self.file = os.fdopen(self.events[0].fd)
+ def read(self):
+ bytes = 8 * (1 + len(self.events))
+ fmt = 'xxxxxxxx' + 'q' * len(self.events)
+ return dict(zip([event.name for event in self.events],
+ struct.unpack(fmt, self.file.read(bytes))))
+
+class Event(object):
+ def __init__(self, group, name, event_set, tracepoint, filter = None):
+ self.name = name
+ attr = perf_event_attr()
+ attr.type = PERF_TYPE_TRACEPOINT
+ attr.size = ctypes.sizeof(attr)
+ id_path = os.path.join(sys_tracing, 'events', event_set,
+ tracepoint, 'id')
+ id = int(file(id_path).read())
+ attr.config = id
+ attr.sample_type = (PERF_SAMPLE_RAW
+ | PERF_SAMPLE_TIME
+ | PERF_SAMPLE_CPU)
+ attr.sample_period = 1
+ attr.read_format = PERF_FORMAT_GROUP
+ group_leader = -1
+ if group.events:
+ group_leader = group.events[0].fd
+ fd = _perf_event_open(attr, -1, group.cpu, group_leader, 0)
+ if fd == -1:
+ raise Exception('perf_event_open failed')
+ if filter:
+ import fcntl
+ fcntl.ioctl(fd, 0x40082406, filter)
+ self.fd = fd
+ def enable(self):
+ import fcntl
+ fcntl.ioctl(self.fd, 0x00002400, 0)
+ def disable(self):
+ import fcntl
+ fcntl.ioctl(self.fd, 0x00002401, 0)
+
+class TracepointProvider(object):
+ def __init__(self):
+ path = os.path.join(sys_tracing, 'events', 'vhost')
+ fields = [f
+ for f in os.listdir(path)
+ if os.path.isdir(os.path.join(path, f))]
+ extra = []
+ for f in fields:
+ if f in filters:
+ subfield, values = filters[f]
+ for name, number in values.iteritems():
+ # kvm_exit(MMIO)
+ extra.append(f + '(' + name + ')')
+ fields += extra
+ self._setup(fields)
+ self.select(fields)
+ def fields(self):
+ return self._fields
+ def _setup(self, _fields):
+ self._fields = _fields
+ cpure = r'cpu([0-9]+)'
+ self.cpus = [int(re.match(cpure, x).group(1))
+ for x in os.listdir('/sys/devices/system/cpu')
+ if re.match(cpure, x)]
+ import resource
+ nfiles = len(self.cpus) * 1000
+ resource.setrlimit(resource.RLIMIT_NOFILE, (nfiles, nfiles))
+ events = []
+ self.group_leaders = []
+ for cpu in self.cpus:
+ group = Group(cpu)
+ for name in _fields:
+ tracepoint = name
+ filter = None
+ # for field like kvm_exit(MMIO)
+ m = re.match(r'(.*)\((.*)\)', name)
+ if m:
+ tracepoint, sub = m.groups()
+ filter = '%s==%s\0' % (filters[tracepoint][0],
+ filters[tracepoint][1][sub])
+ event = group.add_event(name, event_set = 'vhost',
+ tracepoint = tracepoint,
+ filter = filter)
+ self.group_leaders.append(group)
+ def select(self, fields):
+ for group in self.group_leaders:
+ for event in group.events:
+ if event.name in fields:
+ event.enable()
+ else:
+ event.disable()
+ def read(self):
+ from collections import defaultdict
+ ret = defaultdict(int)
+ for group in self.group_leaders:
+ for name, val in group.read().iteritems():
+ ret[name] += val
+ return ret
+
+class Stats:
+ def __init__(self, provider, fields = None):
+ self.provider = provider
+ self.fields_filter = fields
+ self._update()
+ def _update(self):
+ def wanted(key):
+ import re
+ if not self.fields_filter:
+ return True
+ return re.match(self.fields_filter, key) is not None
+ self.values = dict([(key, None)
+ for key in provider.fields()
+ if wanted(key)])
+ self.provider.select(self.values.keys())
+ def set_fields_filter(self, fields_filter):
+ self.fields_filter = fields_filter
+ self._update()
+ def get(self):
+ new = self.provider.read()
+ for key in self.provider.fields():
+ oldval = self.values.get(key, (0, 0))
+ newval = new[key]
+ newdelta = None
+ if oldval is not None:
+ newdelta = newval - oldval[0]
+ self.values[key] = (newval, newdelta)
+ return self.values
+
+if not os.access('/sys/kernel/debug', os.F_OK):
+ print 'Please enable CONFIG_DEBUG_FS in your kernel'
+ sys.exit(1)
+if not os.access('/sys/module/vhost_net', os.F_OK):
+ print 'Please make sure vhost module are loaded'
+ sys.exit(1)
+
+label_width = 40
+number_width = 10
+
+def tui(screen, stats):
+ curses.use_default_colors()
+ curses.noecho()
+ drilldown = False
+ fields_filter = stats.fields_filter
+ def update_drilldown():
+ if not fields_filter:
+ if drilldown:
+ stats.set_fields_filter(None)
+ else:
+ stats.set_fields_filter(r'^[^\(]*$')
+ update_drilldown()
+ def refresh(sleeptime):
+ screen.erase()
+ screen.addstr(0, 0, 'vhost statistics')
+ row = 2
+ s = stats.get()
+ def sortkey(x):
+ if s[x][1]:
+ return (-s[x][1], -s[x][0])
+ else:
+ return (0, -s[x][0])
+ for key in sorted(s.keys(), key = sortkey):
+ if row >= screen.getmaxyx()[0]:
+ break
+ values = s[key]
+ if not values[0] and not values[1]:
+ break
+ col = 1
+ screen.addstr(row, col, key)
+ col += label_width
+ screen.addstr(row, col, '%10d' % (values[0],))
+ col += number_width
+ if values[1] is not None:
+ screen.addstr(row, col, '%8d' % (values[1] / sleeptime,))
+ row += 1
+ screen.refresh()
+
+ sleeptime = 0.25
+ while True:
+ refresh(sleeptime)
+ curses.halfdelay(int(sleeptime * 10))
+ sleeptime = 3
+ try:
+ c = screen.getkey()
+ if c == 'x':
+ drilldown = not drilldown
+ update_drilldown()
+ if c == 'q':
+ break
+ except KeyboardInterrupt:
+ break
+ except curses.error:
+ continue
+
+def batch(stats):
+ s = stats.get()
+ time.sleep(1)
+ s = stats.get()
+ for key in sorted(s.keys()):
+ values = s[key]
+ print '%-22s%10d%10d' % (key, values[0], values[1])
+
+def log(stats):
+ keys = sorted(stats.get().iterkeys())
+ def banner():
+ for k in keys:
+ print '%10s' % k[0:9],
+ print
+ def statline():
+ s = stats.get()
+ for k in keys:
+ print ' %9d' % s[k][1],
+ print
+ line = 0
+ banner_repeat = 20
+ while True:
+ time.sleep(1)
+ if line % banner_repeat == 0:
+ banner()
+ statline()
+ line += 1
+
+options = optparse.OptionParser()
+options.add_option('-1', '--once', '--batch',
+ action = 'store_true',
+ default = False,
+ dest = 'once',
+ help = 'run in batch mode for one second',
+ )
+options.add_option('-l', '--log',
+ action = 'store_true',
+ default = False,
+ dest = 'log',
+ help = 'run in logging mode (like vmstat)',
+ )
+options.add_option('-f', '--fields',
+ action = 'store',
+ default = None,
+ dest = 'fields',
+ help = 'fields to display (regex)',
+ )
+(options, args) = options.parse_args(sys.argv)
+
+try:
+ provider = TracepointProvider()
+except:
+ print "Could not initialize tracepoint"
+ sys.exit(1)
+
+stats = Stats(provider, fields = options.fields)
+
+if options.log:
+ log(stats)
+elif not options.once:
+ import curses.wrapper
+ curses.wrapper(tui, stats)
+else:
+ batch(stats)
^ permalink raw reply related
* [PATCH 1/2] vhost: basic tracepoints
From: Jason Wang @ 2012-04-10 2:58 UTC (permalink / raw)
To: netdev, virtualization, linux-kernel, kvm, mst
In-Reply-To: <20120410025327.49693.93562.stgit@amd-6168-8-1.englab.nay.redhat.com>
To help for the performance optimizations and debugging, this patch tracepoints
for vhost. Pay attention that the tracepoints are only for vhost, net code are
not touched.
Two kinds of activities were traced: virtio and vhost work.
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/vhost/trace.h | 153 +++++++++++++++++++++++++++++++++++++++++++++++++
drivers/vhost/vhost.c | 17 +++++
2 files changed, 168 insertions(+), 2 deletions(-)
create mode 100644 drivers/vhost/trace.h
diff --git a/drivers/vhost/trace.h b/drivers/vhost/trace.h
new file mode 100644
index 0000000..0423899
--- /dev/null
+++ b/drivers/vhost/trace.h
@@ -0,0 +1,153 @@
+#if !defined(_TRACE_VHOST_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_VHOST_H
+
+#include <linux/tracepoint.h>
+#include "vhost.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM vhost
+
+/*
+ * Tracepoint for updating used flag.
+ */
+TRACE_EVENT(vhost_virtio_update_used_flags,
+ TP_PROTO(struct vhost_virtqueue *vq),
+ TP_ARGS(vq),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ __field(u16, used_flags)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ __entry->used_flags = vq->used_flags;
+ ),
+
+ TP_printk("vhost update used flag %x to vq %p notify %s",
+ __entry->used_flags, __entry->vq,
+ (__entry->used_flags & VRING_USED_F_NO_NOTIFY) ?
+ "disabled" : "enabled")
+);
+
+/*
+ * Tracepoint for updating avail event.
+ */
+TRACE_EVENT(vhost_virtio_update_avail_event,
+ TP_PROTO(struct vhost_virtqueue *vq),
+ TP_ARGS(vq),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ __field(u16, avail_idx)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ __entry->avail_idx = vq->avail_idx;
+ ),
+
+ TP_printk("vhost update avail idx %u(%u) for vq %p",
+ __entry->avail_idx, __entry->avail_idx %
+ __entry->vq->num, __entry->vq)
+);
+
+/*
+ * Tracepoint for processing descriptor.
+ */
+TRACE_EVENT(vhost_virtio_get_vq_desc,
+ TP_PROTO(struct vhost_virtqueue *vq, unsigned int index,
+ unsigned out, unsigned int in),
+ TP_ARGS(vq, index, out, in),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ __field(unsigned int, head)
+ __field(unsigned int, out)
+ __field(unsigned int, in)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ __entry->head = index;
+ __entry->out = out;
+ __entry->in = in;
+ ),
+
+ TP_printk("vhost get vq %p head %u out %u in %u",
+ __entry->vq, __entry->head, __entry->out, __entry->in)
+
+);
+
+/*
+ * Tracepoint for signal guest.
+ */
+TRACE_EVENT(vhost_virtio_signal,
+ TP_PROTO(struct vhost_virtqueue *vq),
+ TP_ARGS(vq),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_virtqueue *, vq)
+ ),
+
+ TP_fast_assign(
+ __entry->vq = vq;
+ ),
+
+ TP_printk("vhost signal vq %p", __entry->vq)
+);
+
+DECLARE_EVENT_CLASS(vhost_work_template,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work),
+
+ TP_STRUCT__entry(
+ __field(struct vhost_dev *, dev)
+ __field(struct vhost_work *, work)
+ __field(void *, function)
+ ),
+
+ TP_fast_assign(
+ __entry->dev = dev;
+ __entry->work = work;
+ __entry->function = work->fn;
+ ),
+
+ TP_printk("%pf for work %p dev %p",
+ __entry->function, __entry->work, __entry->dev)
+);
+
+DEFINE_EVENT(vhost_work_template, vhost_work_queue_wakeup,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_work_queue_coalesce,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_poll_start,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_poll_stop,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_work_execute_start,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+DEFINE_EVENT(vhost_work_template, vhost_work_execute_end,
+ TP_PROTO(struct vhost_dev *dev, struct vhost_work *work),
+ TP_ARGS(dev, work));
+
+#endif /* _TRACE_VHOST_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../drivers/vhost
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index c14c42b..23f8d85 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -31,6 +31,8 @@
#include <linux/if_arp.h>
#include "vhost.h"
+#define CREATE_TRACE_POINTS
+#include "trace.h"
enum {
VHOST_MEMORY_MAX_NREGIONS = 64,
@@ -50,6 +52,7 @@ static void vhost_poll_func(struct file *file, wait_queue_head_t *wqh,
poll = container_of(pt, struct vhost_poll, table);
poll->wqh = wqh;
add_wait_queue(wqh, &poll->wait);
+ trace_vhost_poll_start(NULL, &poll->work);
}
static int vhost_poll_wakeup(wait_queue_t *wait, unsigned mode, int sync,
@@ -101,6 +104,7 @@ void vhost_poll_start(struct vhost_poll *poll, struct file *file)
void vhost_poll_stop(struct vhost_poll *poll)
{
remove_wait_queue(poll->wqh, &poll->wait);
+ trace_vhost_poll_stop(NULL, &poll->work);
}
static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
@@ -147,7 +151,9 @@ static inline void vhost_work_queue(struct vhost_dev *dev,
list_add_tail(&work->node, &dev->work_list);
work->queue_seq++;
wake_up_process(dev->worker);
- }
+ trace_vhost_work_queue_wakeup(dev, work);
+ } else
+ trace_vhost_work_queue_coalesce(dev, work);
spin_unlock_irqrestore(&dev->work_lock, flags);
}
@@ -221,7 +227,9 @@ static int vhost_worker(void *data)
if (work) {
__set_current_state(TASK_RUNNING);
+ trace_vhost_work_execute_start(dev, work);
work->fn(work);
+ trace_vhost_work_execute_end(dev, work);
} else
schedule();
@@ -1011,6 +1019,7 @@ static int vhost_update_used_flags(struct vhost_virtqueue *vq)
if (vq->log_ctx)
eventfd_signal(vq->log_ctx, 1);
}
+ trace_vhost_virtio_update_used_flags(vq);
return 0;
}
@@ -1030,6 +1039,7 @@ static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event)
if (vq->log_ctx)
eventfd_signal(vq->log_ctx, 1);
}
+ trace_vhost_virtio_update_avail_event(vq);
return 0;
}
@@ -1319,6 +1329,7 @@ int vhost_get_vq_desc(struct vhost_dev *dev, struct vhost_virtqueue *vq,
/* Assume notifications from guest are disabled at this point,
* if they aren't we would need to update avail_event index. */
BUG_ON(!(vq->used_flags & VRING_USED_F_NO_NOTIFY));
+ trace_vhost_virtio_get_vq_desc(vq, head, *out_num, *in_num);
return head;
}
@@ -1485,8 +1496,10 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
void vhost_signal(struct vhost_dev *dev, struct vhost_virtqueue *vq)
{
/* Signal the Guest tell them we used something up. */
- if (vq->call_ctx && vhost_notify(dev, vq))
+ if (vq->call_ctx && vhost_notify(dev, vq)) {
eventfd_signal(vq->call_ctx, 1);
+ trace_vhost_virtio_signal(vq);
+ }
}
/* And here's the combo meal deal. Supersize me! */
^ permalink raw reply related
* [PATCH 0/2] adding tracepoints to vhost
From: Jason Wang @ 2012-04-10 2:58 UTC (permalink / raw)
To: netdev, virtualization, linux-kernel, kvm, mst
To help in vhost analyzing, the following series adding basic tracepoints to
vhost. Operations of both virtqueues and vhost works were traced in current
implementation, net code were untouched. A top-like satistics displaying script
were introduced to help the troubleshooting.
TODO:
- net specific tracepoints?
---
Jason Wang (2):
vhost: basic tracepoints
tools: virtio: add a top-like utility for displaying vhost satistics
drivers/vhost/trace.h | 153 ++++++++++++++++++++
drivers/vhost/vhost.c | 17 ++
tools/virtio/vhost_stat | 360 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 528 insertions(+), 2 deletions(-)
create mode 100644 drivers/vhost/trace.h
create mode 100755 tools/virtio/vhost_stat
--
Jason Wang
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: Glauber Costa @ 2012-04-10 2:51 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F839CF1.5050104@jp.fujitsu.com>
On 04/09/2012 11:37 PM, KAMEZAWA Hiroyuki wrote:
> Hm. What happens in following sequence ?
>
> 1. a memcg is created
> 2. put a task into the memcg, start tcp steam
> 3. set tcp memory limit
>
> The resource used between 2 and 3 will cause the problem finally.
I don't get it. if a task is in memcg, but no limit is set,
that socket will be assigned null memcg, and will stay like that
forever. Only new sockets will have the new memcg pointer.
And previously, we could have the memcg pointer alive, but the jump
labels to be disabled. With the patch I posted, this can't happen
anymore, since the jump labels are guaranteed to live throughout the
whole socket life.
> Then, Dave's request
> ==
> You must either:
>
> 1) Integrate the socket's existing usage when the limit is set.
>
> 2) Avoid accounting completely for a socket that started before
> the limit was set.
> ==
> are not satisfied. So, we need to have a state per sockets, it's accounted
> or not. I'll look into this problem again, today.
>
Of course they are.
Every socket created before we set the limit is not accounted.
This is 2) that Dave mentioned, and it was *always* this way.
The problem here was the opposite: You could disable the jump labels
with sockets still in flight, because we were disabling it based on
the limit being set back to unlimited.
What this patch does, is defer that until the last socket limited dies.
^ permalink raw reply
* Re: [PATCH v3 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:44 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-3-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 7:36), Glauber Costa wrote:
> The last man standing justifying the need for populate() is the
> sock memcg initialization functions. Now that we are able to pass
> a struct mem_cgroup instead of a struct cgroup to the socket
> initialization, there is nothing that stops us from initializing
> everything in create().
>
> Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
> CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
> CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
^ permalink raw reply
* Re: [PATCH v3 1/2] cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:42 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-2-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 7:36), Glauber Costa wrote:
> The only reason cgroup was used, was to be consistent with the populate()
> interface. Now that we're getting rid of it, not only we no longer need
> it, but we also *can't* call it this way.
>
> Since we will no longer rely on populate(), this will be called from
> create(). During create, the association between struct mem_cgroup
> and struct cgroup does not yet exist, since cgroup internals hasn't
> yet initialized its bookkeeping. This means we would not be able
> to draw the memcg pointer from the cgroup pointer in these
> functions, which is highly undesirable.
>
> Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
> CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
> CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
> CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
^ permalink raw reply
* Re: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
From: KAMEZAWA Hiroyuki @ 2012-04-10 2:37 UTC (permalink / raw)
To: Glauber Costa; +Cc: netdev, David Miller, Andrew Morton
In-Reply-To: <4F7F1091.9040204@parallels.com>
(2012/04/07 0:49), Glauber Costa wrote:
> On 03/30/2012 05:44 AM, KAMEZAWA Hiroyuki wrote:
>> Maybe what we can do before lsf/mm summit will be this (avoid warning.)
>> This patch is onto linus's git tree. Patch description is updated.
>>
>> Thanks.
>> -Kame
>> ==
>> From 4ab80f84bbcb02a790342426c1de84aeb17fcbe9 Mon Sep 17 00:00:00 2001
>> From: KAMEZAWA Hiroyuki<kamezawa.hiroyu@jp.fujitsu.com>
>> Date: Thu, 29 Mar 2012 14:59:04 +0900
>> Subject: [PATCH] memcg/tcp: fix warning caused b res->usage go to negative.
>>
>> tcp memcontrol starts accouting after res->limit is set. So, if a sockets
>> starts before setting res->limit, there are already used resource.
>> At setting res->limit, accounting starts. The resource will be uncharged
>> and make res_counter below 0 because they are not charged.
>> This causes warning.
>>
>
> Kame,
>
> Please test the following patch and see if it fixes your problems (I
> tested locally, and it triggers me no warnings running the test script
> you provided + an inbound scp -r copy of an iso directory from a remote
> machine)
>
> When you are reviewing, keep in mind that we're likely to have the same
> problems with slab jump labels - since the slab pages will outlive the
> cgroup as well, and it might be worthy to keep this in mind, and provide
> a central point for the jump labels to be set of on cgroup destruction.
>
Hm. What happens in following sequence ?
1. a memcg is created
2. put a task into the memcg, start tcp steam
3. set tcp memory limit
The resource used between 2 and 3 will cause the problem finally.
Then, Dave's request
==
You must either:
1) Integrate the socket's existing usage when the limit is set.
2) Avoid accounting completely for a socket that started before
the limit was set.
==
are not satisfied. So, we need to have a state per sockets, it's accounted
or not. I'll look into this problem again, today.
Thanks,
-Kame
^ permalink raw reply
* Kernel panic with sysfs adding group for pmu device
From: Brown, Aaron F @ 2012-04-10 2:05 UTC (permalink / raw)
To: netdev@vger.kernel.org
Hi all,
I'm getting a kernel panic on boot with the the net-next tree on a
number of test systems I work with. So far this appears on older Intel
Xeon server platforms that have an ESB based chipset with either an x86
or x86_64 kernel.
Here is the panic I am seeing:
---------------------------------
Starts to boots normally to ...
...
Trying to unpack rootfs image as initramfs...
debug: unmapping init memory f748b000..f77fe000
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<c10d19a0>] internal_create_group+0xdc/0x138
*pde = 00000000
Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC
Modules linked in:
Pid: 1, comm: swapper/0 Not tainted 3.4.0-rc1_net-next_igb_2107cad... #2
Intel /SE7525GP2
EIP: 0060:[<c10d19a0>] EFLAGS: 00010246 CPU: 0
EIP is at internal_create_group+0xdc/0x138
EAX: 00000001 EBX: f4fc0df8 ECX: 00000000 EDX: 00000000
ESI: 00000000 EDI: 00000000 EBP: f58fbf34 ESP: f58fbf14
DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068
CR0: 8005003b CR2: 00000000 CR3: 014fc000 CR4: 000007d0
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: ffff0ff0 DR7: 00000400
Process swapper/0 (pid: 1, ti=f58fa000 task=f58e9c60 task.ti=f58fa000)
Stack:
00000000 f4fc2238 00000000 c146b780 f4fc2238 00000001 c146b80c 00000000
f58fbf3c c10d1a19 f58fbf54 c1188d3f f4fc0df8 f4fc0df0 00000000 00000000
f58fbf90 c11893a1 c1188d81 00000000 00000000 f4fc0df0 f4fc0df8 c14e5f24
Call Trace:
[<c10d1a19>] sysfs_create_group+0xc/0xf
[<c1188d3f>] device_add_groups+0x21/0x4e
[<c11893a1>] device_add+0x2fa/0x4fb
[<c1188d81>] ? device_private_init+0x15/0x49
[<c1188da2>] ? device_private_init+0x36/0x49
[<c10605bb>] pmu_dev_alloc+0x75/0x8e
[<c14a8dbc>] perf_event_sysfs_init+0x3f/0x85
[<c1001159>] do_one_initcall+0x71/0x113
[<c14a8d7d>] ? utsname_sysctl_init+0x11/0x11
[<c149727c>] kernel_init+0xd8/0x161
[<c14971a4>] ? parse_early_options+0x21/0x21
[<c1339ef6>] kernel_thread_helper+0x6/0xd
Code: d7 66 85 c0 74 21 8b 4d e8 8b 14 b1 b9 02 00 00 00 0b 42 04 0f b7
c0 50 8b 45 e4 e8 01 e1 ff ff 89 c7 59 85 c0 75 0f 46 8b 55 e8 <8b> 04
b2 85 c0 75 a5 31 ff eb 27 8b 4d ec 8b 59 08 eb 0f 8b 08
EIP: [<c10d19a0>] internal_create_group+0xdc/0x138 SS:ESP 0068:f58fbf14
CR2: 0000000000000000
---[ end trace e93713a9d40cd06c ]---
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009
---------------------------------
I tried disabling DEBUG_PAGEALLOC as well as
different preempt settings, compiled as single proc, etc... The panic
continued, but modified "Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC" line
to represent the actual settings.
I ran a series of git bisects and found that the patch that introduced
the panics is:
-------------------------------------------
u1460:[0]/usr/src/kernels/net-next> git bisect good
641cc938815dfd09f8fa1ec72deb814f0938ac33 is first bad commit
commit 641cc938815dfd09f8fa1ec72deb814f0938ac33
Author: Jiri Olsa <jolsa@redhat.com>
Date: Thu Mar 15 20:09:14 2012 +0100
perf: Adding sysfs group format attribute for pmu device
Adding sysfs group 'format' attribute for pmu device that
contains a syntax description on how to construct raw events.
The event configuration is described in following
struct pefr_event_attr attributes:
config
config1
config2
Each sysfs attribute within the format attribute group,
describes mapping of name and bitfield definition within
one of above attributes.
eg:
"/sys/...<dev>/format/event" contains "config:0-7"
"/sys/...<dev>/format/umask" contains "config:8-15"
"/sys/...<dev>/format/usr" contains "config:16"
the attribute value syntax is:
line: config ':' bits
config: 'config' | 'config1' | 'config2"
bits: bits ',' bit_term | bit_term
bit_term: VALUE '-' VALUE | VALUE
Adding format attribute definitions for x86 cpu pmus.
Acked-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Link:
http://lkml.kernel.org/n/tip-vhdk5y2hyype9j63prymty36@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
:040000 040000 6997376a7fa63ee143dd365babc373cb298148a4
1779179772124f413d1d1b18fdd6bb3bdd9713c0 M Documentation
:040000 040000 1bbb2bd82a0abee4e9f55c9ccbc0805d4d0040c4
a947cf4cfd048f98904e5fc59b67253258b6f5a3 M arch
:040000 040000 bd74f46a57eb846a2ee7e3d60813bb1c1af2d71a
d95d819d91a7049d3e7355488436c4305319ceac M include
u1460:[0]/usr/src/kernels/net-next_igb-queue>
------------------------------------------------------
^ permalink raw reply
* Re: [PATCH v2 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 1:37 UTC (permalink / raw)
To: Glauber Costa
Cc: Tejun Heo, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko, Balbir Singh
In-Reply-To: <4F83218E.7060502-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
(2012/04/10 2:51), Glauber Costa wrote:
> On 04/09/2012 02:40 PM, Tejun Heo wrote:
>> which BTW seems incorrect even on its
>> own - unmounting and mounting again would probably make the same
>> notifier registered multiple times corrupting notification chain, and
>> ref inc on the parent.
>
>
> For the maintainers: Should I fix those in a new submission, or do you
> intend to do it yourselves?
>
> the refcnt dropping should probably be done in my patch, it is a new
> leak (sorry). The hotplug notifier, as tejun pointed, was already there.
>
> It seems simple enough to fix, so if you guys want, I can bundle it in
> a new submission.
>
Please make notifier fix patch against mm tree, as an independent one.
Thanks,
-Kame
^ permalink raw reply
* Re: [PATCH v2 2/2] cgroup: get rid of populate for memcg
From: KAMEZAWA Hiroyuki @ 2012-04-10 1:35 UTC (permalink / raw)
To: Tejun Heo
Cc: Glauber Costa, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Li Zefan, Johannes Weiner,
Michal Hocko, Balbir Singh
In-Reply-To: <20120409174042.GA7522-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
(2012/04/10 2:40), Tejun Heo wrote:
> (cc'ing other memcg ppl just in case)
>
> Hello,
>
> I don't think the error handling is correct here.
>
> On Fri, Apr 06, 2012 at 08:04:10PM +0400, Glauber Costa wrote:
>> The last man standing justifying the need for populate() is the
>> sock memcg initialization functions. Now that we are able to pass
>> a struct mem_cgroup instead of a struct cgroup to the socket
>> initialization, there is nothing that stops us from initializing
>> everything in create().
>>
>> Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
>> CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
>> ---
> ...
>> @@ -5010,7 +5010,9 @@ mem_cgroup_create(struct cgroup *cont)
>> memcg->move_charge_at_immigrate = 0;
>> mutex_init(&memcg->thresholds_lock);
>> spin_lock_init(&memcg->move_lock);
>> - return &memcg->css;
>> +
>> + if (!memcg_init_kmem(memcg, &mem_cgroup_subsys))
>> + return &memcg->css;
>> free_out:
>> __mem_cgroup_free(memcg);
>> return ERR_PTR(error);
>
> So, the control is just falling through free_out: on kmem init
> failure; however, there seem to be stuff which needs to be undone -
> hotcpu_notifier() registration, which BTW seems incorrect even on its
> own - unmounting and mounting again would probably make the same
> notifier registered multiple times corrupting notification chain, and
> ref inc on the parent.
>
ok, it should be fixed.
> It probably would be best to reorganize the function slightly such
> that, it's organized as...
>
> 1. alloc
> 2. init stuff w/o other side effects
> 3. make side effects
>
> and add kmemcg init at the end of the second step.
>
> Also, memcg maintainers, once the patches get updated and acked, I'd
> like to route them through cgroup tree so that I can kill ->populate
> there. cgroup/for-3.5 is stable branch which can be pulled into other
> trees including the memcg one. Would that be okay?
>
Hm, I'm okay with that but.....Michal ?
Thanks,
-Kame
^ permalink raw reply
* linux-next: manual merge of the wireless-next tree with the net-next tree
From: Stephen Rothwell @ 2012-04-10 1:32 UTC (permalink / raw)
To: John W. Linville
Cc: linux-next, linux-kernel, David Miller, netdev,
Meenakshi Venkataraman, Wey-Yi Guy
[-- Attachment #1: Type: text/plain, Size: 1442 bytes --]
Hi John,
Today's linux-next merge of the wireless-next tree got a conflict in
drivers/net/wireless/iwlwifi/iwl-testmode.c between commit d33e152e1edd
("iwlwifi: Stop using NLA_PUT*()") from the net-next tree and commit
a42506eb27aa ("iwlwifi: move ucode_type from shared to op_mode") from the
wireless-next tree.
I fixed it up (see below) and can carry the fix as necessary.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --cc drivers/net/wireless/iwlwifi/iwl-testmode.c
index a54e20e,d65dac8..0000000
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c
@@@ -609,10 -605,9 +612,10 @@@ static int iwl_testmode_driver(struct i
inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
}
- if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type) ||
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size);
- NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size);
++ if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) ||
+ nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size))
+ goto nla_put_failure;
status = cfg80211_testmode_reply(skb);
if (status < 0)
IWL_ERR(priv, "Error sending msg : %d\n", status);
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 5/9] ipvs: use adaptive pause in master thread
From: Pablo Neira Ayuso @ 2012-04-09 23:08 UTC (permalink / raw)
To: Julian Anastasov
Cc: Simon Horman, lvs-devel, netdev, netfilter-devel, Wensong Zhang
In-Reply-To: <alpine.LFD.2.00.1204082221440.6964@ja.ssi.bg>
Hi Julian,
On Sun, Apr 08, 2012 at 11:12:53PM +0300, Julian Anastasov wrote:
>
> Hello,
>
> On Thu, 5 Apr 2012, Pablo Neira Ayuso wrote:
>
> > I think you can control when the kernel thread is woken up with a
> > counting semaphore. The counter of that semaphore will be initially
> > set to zero. Then, you can up() the semaphore once per new buffer
> > that you enqueue to the sender.
> >
> > feeder:
> > add message to sync buffer
> > if buffer full:
> > enqueue buffer to sender_thread
> > up(s)
> >
> > sender_thread:
> > while (1) {
> > down(s)
> > retrieve message from queue
> > send message
> > }
> >
> > It seems to me like the classical producer/consumer problem that you
> > can resolve with semaphores.
>
> May be it is possible to use up/down but we
> have to handle the kthread_should_stop check and also
> I prefer to reduce the wakeup events. So, I'm trying
> another solution which is appended just for review.
You can still use kthread_should_stop inside a wrapper function
that calls kthread_stop and up() the semaphore.
sync_stop:
kthread_stop(k)
up(s)
kthread_routine:
while(1) {
down(s)
if (kthread_should_stop(k))
break;
get sync msg
send sync msg
}
BTW, each up() does not necessarily mean one wakeup event. up() will
delivery only one wakeup event for one process that has been already
awaken.
> > Under congestion the situation is complicated. At some point you'll
> > end up dropping messages.
> >
> > You may want to increase the socket queue to delay the moment at which
> > we start dropping messages. You can expose the socke buffer length via
> > /proc interface I guess (not sure if you're already doing that or
> > suggesting to use the global socket buffer length).
>
> I'm still thinking if sndbuf value should be exported,
> currently users have to modify the global default/max value.
I think it's a good idea.
> But in below version I'm trying to handle the sndbuf overflow
> by blocking for write_space event. By this way we should work
> with any sndbuf configuration.
You seem to be defering the overrun problem by using a longer
intermediate queue than the socket buffer. Then, that queue can be
tuned by the user via sysctl. It may happen under heavy stress that
your intermediate queue gets full again, then you'll have to drop
packets at some point.
> > You also can define some mechanism to reduce the amount of events,
> > some state filtering so you only propagate important states.
> >
> > Some partially reliable protocol, so the backup can request messages
> > that got lost in a smart way would can also in handy. Basically, the
> > master only retransmits the current state, not the whole sequence of
> > messages (this is good under congestion, since you save messages).
> > I implement that in conntrackd, but that's more complex solution,
> > of course. I'd start with something simple.
>
> The patch "reduce sync rate with time thresholds"
> that follows the discussed one in the changeset has such
> purpose to reduce the events, in tests the sync traffic is
> reduced ~10 times. But it does not modify the current
> protocol, it adds a very limited logic for retransmissions.
Not directly related to this, but I'd prefer if any retransmission
support (or any new feature) gets added in follow-up patches. So we
can things separated in logic pieces. Thanks.
^ permalink raw reply
* Re: [PATCH v17 15/15] Documentation: prctl/seccomp_filter
From: Will Drewry @ 2012-04-09 22:47 UTC (permalink / raw)
To: Ryan Ware, Markus Gutschke, Andrew Morton
Cc: linux-kernel, linux-security-module, linux-arch, linux-doc,
kernel-hardening, netdev, x86, arnd, davem, hpa, mingo, oleg,
peterz, rdunlap, mcgrathr, tglx, luto, eparis, serge.hallyn, djm,
scarybeasts, indan, pmoore, corbet, eric.dumazet, coreyb,
keescook, jmorris
In-Reply-To: <CBA89B80.3C770%ware@linux.intel.com>
On Mon, Apr 9, 2012 at 3:58 PM, Ryan Ware <ware@linux.intel.com> wrote:
>
> On 4/9/12 1:47 PM, "Markus Gutschke" <markus@chromium.org> wrote:
>
>>No matter what you do, please leave the samples accessible somewhere.
>>They proved incredibly useful in figuring out how the API works. I am
>>sure, other developers are going to appreciate them as well.
>>
>>Alternatively, if you don't want to include the samples with the
>>kernel sources, figure out how you can include a sample in the
>>official manual page for prctl().
>>
>
> I second this! They are extremely useful.
>
> Ryan
In that case, would it make sense to put up a separate tools/testing
patch and leave samples where they lie? (I'd _love_ to keep this patch
series from acquiring another 1000 lines, but either way works :)
My current tester and harness lives here:
https://github.com/redpig/seccomp/blob/master/tests/
and the licensing can be sorted out prior to a patch mail.
thanks!
will
^ permalink raw reply
* Re: [PATCH v3 2/2] cgroup: get rid of populate for memcg
From: Tejun Heo @ 2012-04-09 22:42 UTC (permalink / raw)
To: Glauber Costa
Cc: netdev, cgroups, Li Zefan, kamezawa.hiroyu, Johannes Weiner,
Michal Hocko
In-Reply-To: <1334010994-23301-3-git-send-email-glommer@parallels.com>
On Mon, Apr 09, 2012 at 07:36:34PM -0300, Glauber Costa wrote:
> The last man standing justifying the need for populate() is the
> sock memcg initialization functions. Now that we are able to pass
> a struct mem_cgroup instead of a struct cgroup to the socket
> initialization, there is nothing that stops us from initializing
> everything in create().
>
> Signed-off-by: Glauber Costa <glommer@parallels.com>
> CC: Tejun Heo <tj@kernel.org>
> CC: Li Zefan <lizefan@huawei.com>
> CC: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> CC: Johannes Weiner <hannes@cmpxchg.org>
> CC: Michal Hocko <mhocko@suse.cz>
Will apply once memcg maintainers ack.
Thanks.
--
tejun
^ permalink raw reply
* [PATCH v3 2/2] cgroup: get rid of populate for memcg
From: Glauber Costa @ 2012-04-09 22:36 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A, Glauber Costa,
Johannes Weiner, Michal Hocko
In-Reply-To: <1334010994-23301-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The last man standing justifying the need for populate() is the
sock memcg initialization functions. Now that we are able to pass
a struct mem_cgroup instead of a struct cgroup to the socket
initialization, there is nothing that stops us from initializing
everything in create().
Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
---
mm/memcontrol.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 704054d..02b01d2 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,7 +4640,7 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return mem_cgroup_sockets_init(memcg, ss);
};
@@ -4650,7 +4650,7 @@ static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
+static int memcg_init_kmem(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
@@ -5010,6 +5010,17 @@ mem_cgroup_create(struct cgroup *cont)
memcg->move_charge_at_immigrate = 0;
mutex_init(&memcg->thresholds_lock);
spin_lock_init(&memcg->move_lock);
+
+ error = memcg_init_kmem(memcg, &mem_cgroup_subsys);
+ if (error) {
+ /*
+ * We call put now because our (and parent's) refcnts
+ * are already in place. mem_cgroup_put() will internally
+ * call __mem_cgroup_free, so return directly
+ */
+ mem_cgroup_put(memcg);
+ return ERR_PTR(error);
+ }
return &memcg->css;
free_out:
__mem_cgroup_free(memcg);
@@ -5032,13 +5043,6 @@ static void mem_cgroup_destroy(struct cgroup *cont)
mem_cgroup_put(memcg);
}
-static int mem_cgroup_populate(struct cgroup_subsys *ss,
- struct cgroup *cont)
-{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- return register_kmem_files(memcg, ss);
-}
-
#ifdef CONFIG_MMU
/* Handlers for move charge at task migration. */
#define PRECHARGE_COUNT_AT_ONCE 256
@@ -5622,7 +5626,6 @@ struct cgroup_subsys mem_cgroup_subsys = {
.create = mem_cgroup_create,
.pre_destroy = mem_cgroup_pre_destroy,
.destroy = mem_cgroup_destroy,
- .populate = mem_cgroup_populate,
.can_attach = mem_cgroup_can_attach,
.cancel_attach = mem_cgroup_cancel_attach,
.attach = mem_cgroup_move_task,
--
1.7.7.6
^ permalink raw reply related
* [PATCH v3 1/2] cgroup: pass struct mem_cgroup instead of struct cgroup to socket memcg
From: Glauber Costa @ 2012-04-09 22:36 UTC (permalink / raw)
To: Tejun Heo
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Li Zefan, kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A, Glauber Costa,
Johannes Weiner, Michal Hocko
In-Reply-To: <1334010994-23301-1-git-send-email-glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
The only reason cgroup was used, was to be consistent with the populate()
interface. Now that we're getting rid of it, not only we no longer need
it, but we also *can't* call it this way.
Since we will no longer rely on populate(), this will be called from
create(). During create, the association between struct mem_cgroup
and struct cgroup does not yet exist, since cgroup internals hasn't
yet initialized its bookkeeping. This means we would not be able
to draw the memcg pointer from the cgroup pointer in these
functions, which is highly undesirable.
Signed-off-by: Glauber Costa <glommer-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
CC: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
CC: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
CC: Kamezawa Hiroyuki <kamezawa.hiroyu-+CUm20s59erQFUHtdCDX3A@public.gmane.org>
CC: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
CC: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
---
include/net/sock.h | 12 ++++++------
include/net/tcp_memcontrol.h | 4 ++--
mm/memcontrol.c | 24 +++++++++---------------
net/core/sock.c | 10 +++++-----
net/ipv4/tcp_memcontrol.c | 6 ++----
5 files changed, 24 insertions(+), 32 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index a6ba1f8..b3ebe6b 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -70,16 +70,16 @@
struct cgroup;
struct cgroup_subsys;
#ifdef CONFIG_NET
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp);
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg);
#else
static inline
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
static inline
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -900,9 +900,9 @@ struct proto {
* This function has to setup any files the protocol want to
* appear in the kmem cgroup filesystem.
*/
- int (*init_cgroup)(struct cgroup *cgrp,
+ int (*init_cgroup)(struct mem_cgroup *memcg,
struct cgroup_subsys *ss);
- void (*destroy_cgroup)(struct cgroup *cgrp);
+ void (*destroy_cgroup)(struct mem_cgroup *memcg);
struct cg_proto *(*proto_cgroup)(struct mem_cgroup *memcg);
#endif
};
diff --git a/include/net/tcp_memcontrol.h b/include/net/tcp_memcontrol.h
index 48410ff..7df18bc 100644
--- a/include/net/tcp_memcontrol.h
+++ b/include/net/tcp_memcontrol.h
@@ -12,8 +12,8 @@ struct tcp_memcontrol {
};
struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss);
-void tcp_destroy_cgroup(struct cgroup *cgrp);
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss);
+void tcp_destroy_cgroup(struct mem_cgroup *memcg);
unsigned long long tcp_max_memory(const struct mem_cgroup *memcg);
void tcp_prot_mem(struct mem_cgroup *memcg, long val, int idx);
#endif /* _TCP_MEMCG_H */
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index bef1142..704054d 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4640,29 +4640,22 @@ static int mem_control_numa_stat_open(struct inode *unused, struct file *file)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
- /*
- * Part of this would be better living in a separate allocation
- * function, leaving us with just the cgroup tree population work.
- * We, however, depend on state such as network's proto_list that
- * is only initialized after cgroup creation. I found the less
- * cumbersome way to deal with it to defer it all to populate time
- */
- return mem_cgroup_sockets_init(cont, ss);
+ return mem_cgroup_sockets_init(memcg, ss);
};
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
- mem_cgroup_sockets_destroy(cont);
+ mem_cgroup_sockets_destroy(memcg);
}
#else
-static int register_kmem_files(struct cgroup *cont, struct cgroup_subsys *ss)
+static int register_kmem_files(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
return 0;
}
-static void kmem_cgroup_destroy(struct cgroup *cont)
+static void kmem_cgroup_destroy(struct mem_cgroup *memcg)
{
}
#endif
@@ -5034,7 +5027,7 @@ static void mem_cgroup_destroy(struct cgroup *cont)
{
struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
- kmem_cgroup_destroy(cont);
+ kmem_cgroup_destroy(memcg);
mem_cgroup_put(memcg);
}
@@ -5042,7 +5035,8 @@ static void mem_cgroup_destroy(struct cgroup *cont)
static int mem_cgroup_populate(struct cgroup_subsys *ss,
struct cgroup *cont)
{
- return register_kmem_files(cont, ss);
+ struct mem_cgroup *memcg = mem_cgroup_from_cont(cont);
+ return register_kmem_files(memcg, ss);
}
#ifdef CONFIG_MMU
diff --git a/net/core/sock.c b/net/core/sock.c
index b2e14c0..878f744 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -140,7 +140,7 @@ static DEFINE_MUTEX(proto_list_mutex);
static LIST_HEAD(proto_list);
#ifdef CONFIG_CGROUP_MEM_RES_CTLR_KMEM
-int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
struct proto *proto;
int ret = 0;
@@ -148,7 +148,7 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
mutex_lock(&proto_list_mutex);
list_for_each_entry(proto, &proto_list, node) {
if (proto->init_cgroup) {
- ret = proto->init_cgroup(cgrp, ss);
+ ret = proto->init_cgroup(memcg, ss);
if (ret)
goto out;
}
@@ -159,19 +159,19 @@ int mem_cgroup_sockets_init(struct cgroup *cgrp, struct cgroup_subsys *ss)
out:
list_for_each_entry_continue_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
return ret;
}
-void mem_cgroup_sockets_destroy(struct cgroup *cgrp)
+void mem_cgroup_sockets_destroy(struct mem_cgroup *memcg)
{
struct proto *proto;
mutex_lock(&proto_list_mutex);
list_for_each_entry_reverse(proto, &proto_list, node)
if (proto->destroy_cgroup)
- proto->destroy_cgroup(cgrp);
+ proto->destroy_cgroup(memcg);
mutex_unlock(&proto_list_mutex);
}
#endif
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 8f1753d..1517037 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -18,7 +18,7 @@ static void memcg_tcp_enter_memory_pressure(struct sock *sk)
}
EXPORT_SYMBOL(memcg_tcp_enter_memory_pressure);
-int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
+int tcp_init_cgroup(struct mem_cgroup *memcg, struct cgroup_subsys *ss)
{
/*
* The root cgroup does not use res_counters, but rather,
@@ -28,7 +28,6 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
struct res_counter *res_parent = NULL;
struct cg_proto *cg_proto, *parent_cg;
struct tcp_memcontrol *tcp;
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct mem_cgroup *parent = parent_mem_cgroup(memcg);
struct net *net = current->nsproxy->net_ns;
@@ -61,9 +60,8 @@ int tcp_init_cgroup(struct cgroup *cgrp, struct cgroup_subsys *ss)
}
EXPORT_SYMBOL(tcp_init_cgroup);
-void tcp_destroy_cgroup(struct cgroup *cgrp)
+void tcp_destroy_cgroup(struct mem_cgroup *memcg)
{
- struct mem_cgroup *memcg = mem_cgroup_from_cont(cgrp);
struct cg_proto *cg_proto;
struct tcp_memcontrol *tcp;
u64 val;
--
1.7.7.6
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox