* [PATCH net v4 3/4] r8152: support stopping/waking tx queue
From: Hayes Wang @ 2013-11-19 3:25 UTC (permalink / raw)
To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang
In-Reply-To: <1384831511-1625-1-git-send-email-hayeswang@realtek.com>
The maximum packet number which a tx aggregation buffer could contain
is the buffer size / (packet size + descriptor size).
If the tx buffer is empty and the tx queue length is more than the
maximum value which is defined above, stop the tx queue. Wake the tx
queue after any queued packet is filled in a available tx buffer.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/usb/r8152.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8a786b6..0ac2b53 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -365,6 +365,7 @@ struct r8152 {
struct mii_if_info mii;
int intr_interval;
u32 msg_enable;
+ u32 tx_qlen;
u16 ocp_base;
u8 *intr_buff;
u8 version;
@@ -1173,6 +1174,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
}
+ if (netif_queue_stopped(tp->netdev))
+ netif_wake_queue(tp->netdev);
+
usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
agg->head, (int)(tx_data - (u8 *)agg->head),
(usb_complete_t)write_bulk_callback, agg);
@@ -1393,6 +1397,10 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
skb_queue_tail(&tp->tx_queue, skb);
+ if (list_empty(&tp->tx_free) &&
+ skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
+ netif_stop_queue(netdev);
+
if (!list_empty(&tp->tx_free))
tasklet_schedule(&tp->tl);
@@ -1423,6 +1431,14 @@ static void rtl8152_nic_reset(struct r8152 *tp)
}
}
+static void set_tx_qlen(struct r8152 *tp)
+{
+ struct net_device *netdev = tp->netdev;
+
+ tp->tx_qlen = rx_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN +
+ sizeof(struct tx_desc));
+}
+
static inline u8 rtl8152_get_speed(struct r8152 *tp)
{
return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS);
@@ -1434,6 +1450,7 @@ static int rtl8152_enable(struct r8152 *tp)
int i, ret;
u8 speed;
+ set_tx_qlen(tp);
speed = rtl8152_get_speed(tp);
if (speed & _10bps) {
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
--
1.8.3.1
^ permalink raw reply related
* [PATCH net v4 4/4] r8152: fix incorrect type in assignment
From: Hayes Wang @ 2013-11-19 3:25 UTC (permalink / raw)
To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang
In-Reply-To: <1384831511-1625-1-git-send-email-hayeswang@realtek.com>
The data from the hardware should be little endian. Correct the
declaration.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/usb/r8152.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0ac2b53..fb35e6e 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -307,22 +307,22 @@ enum rtl8152_flags {
#define MCU_TYPE_USB 0x0000
struct rx_desc {
- u32 opts1;
+ __le32 opts1;
#define RX_LEN_MASK 0x7fff
- u32 opts2;
- u32 opts3;
- u32 opts4;
- u32 opts5;
- u32 opts6;
+ __le32 opts2;
+ __le32 opts3;
+ __le32 opts4;
+ __le32 opts5;
+ __le32 opts6;
};
struct tx_desc {
- u32 opts1;
+ __le32 opts1;
#define TX_FS (1 << 31) /* First segment of a packet */
#define TX_LS (1 << 30) /* Final segment of a packet */
#define TX_LEN_MASK 0x3ffff
- u32 opts2;
+ __le32 opts2;
#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */
#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */
#define IPV4_CS (1 << 29) /* Calculate IPv4 checksum */
@@ -877,7 +877,7 @@ static void write_bulk_callback(struct urb *urb)
static void intr_callback(struct urb *urb)
{
struct r8152 *tp;
- __u16 *d;
+ __le16 *d;
int status = urb->status;
int res;
--
1.8.3.1
^ permalink raw reply related
* [PATCH net v4 2/4] r8152: modify the tx flow
From: Hayes Wang @ 2013-11-19 3:25 UTC (permalink / raw)
To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang
In-Reply-To: <1384831511-1625-1-git-send-email-hayeswang@realtek.com>
Remove the code for sending the packet in the rtl8152_start_xmit().
Let rtl8152_start_xmit() to queue the packet only, and schedule a
tasklet to send the queued packets. This simplify the code and make
sure all the packet would be sent by the original order.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/usb/r8152.c | 46 +++-------------------------------------------
1 file changed, 3 insertions(+), 43 deletions(-)
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 428600d..8a786b6 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1388,53 +1388,13 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
struct net_device *netdev)
{
struct r8152 *tp = netdev_priv(netdev);
- struct net_device_stats *stats = rtl8152_get_stats(netdev);
- unsigned long flags;
- struct tx_agg *agg = NULL;
- struct tx_desc *tx_desc;
- unsigned int len;
- u8 *tx_data;
- int res;
skb_tx_timestamp(skb);
- /* If tx_queue is not empty, it means at least one previous packt */
- /* is waiting for sending. Don't send current one before it. */
- if (skb_queue_empty(&tp->tx_queue))
- agg = r8152_get_tx_agg(tp);
-
- if (!agg) {
- skb_queue_tail(&tp->tx_queue, skb);
- return NETDEV_TX_OK;
- }
-
- tx_desc = (struct tx_desc *)agg->head;
- tx_data = agg->head + sizeof(*tx_desc);
- agg->skb_num = agg->skb_len = 0;
+ skb_queue_tail(&tp->tx_queue, skb);
- len = skb->len;
- r8152_tx_csum(tp, tx_desc, skb);
- memcpy(tx_data, skb->data, len);
- dev_kfree_skb_any(skb);
- agg->skb_num++;
- agg->skb_len += len;
- usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
- agg->head, len + sizeof(*tx_desc),
- (usb_complete_t)write_bulk_callback, agg);
- res = usb_submit_urb(agg->urb, GFP_ATOMIC);
- if (res) {
- /* Can we get/handle EPIPE here? */
- if (res == -ENODEV) {
- netif_device_detach(tp->netdev);
- } else {
- netif_warn(tp, tx_err, netdev,
- "failed tx_urb %d\n", res);
- stats->tx_dropped++;
- spin_lock_irqsave(&tp->tx_lock, flags);
- list_add_tail(&agg->list, &tp->tx_free);
- spin_unlock_irqrestore(&tp->tx_lock, flags);
- }
- }
+ if (!list_empty(&tp->tx_free))
+ tasklet_schedule(&tp->tl);
return NETDEV_TX_OK;
}
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 2/2] ipv6: use sk_v6_copy_addrs when memcpy struct ipv6_pinfo
From: wangweidong @ 2013-11-19 3:32 UTC (permalink / raw)
To: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, vyasevich,
nhorman, dccp, netdev, linux-sctp, dingtianhong
In-Reply-To: <20131119031408.GQ16541@order.stressinduktion.org>
On 2013/11/19 11:14, Hannes Frederic Sowa wrote:
> On Tue, Nov 19, 2013 at 10:47:27AM +0800, Wang Weidong wrote:
>> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
>> index 0740f93..83d011e 100644
>> --- a/net/ipv6/tcp_ipv6.c
>> +++ b/net/ipv6/tcp_ipv6.c
>> @@ -1116,6 +1116,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
>> newtp = tcp_sk(newsk);
>>
>> memcpy(newnp, np, sizeof(struct ipv6_pinfo));
>> + /* Don't forget copy the rcv_saddr and daddr when
>> + * copy ipv6_pinfo.
>> + */
>> + sk_v6_copy_addrs(newsk, sk);
>>
>> ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);
>>
>
> Hmm, how did you spot this?
>
> Greetings,
>
> Hannes
>
When I did the lksctp-tools(1.0.15)/src/func_tests/test_getname_v6, I got a Segmentation fault.
So I try to resolve it. I found the sctp_accept will call sctp_v6_create_accept_sk in IPV6,
the function will memcpy the ipv6_pinfo, and not copy the sk_v6_rcv_saddr. But the getsockname
will read the sk_v6_rcv_saddr, and the value is not true.
>
> .
>
^ permalink raw reply
* Re: [PATCH net-next] veth: extend features to support tunneling
From: Alexei Starovoitov @ 2013-11-19 3:51 UTC (permalink / raw)
To: David Stevens
Cc: David Miller, Eric Dumazet, Eric Dumazet, John Fastabend,
Michael S. Tsirkin, netdev@vger.kernel.org, netdev-owner,
Or Gerlitz, Stephen Hemminger
In-Reply-To: <OFF76C3619.82D931F7-ON85257C27.005F4843-85257C27.006270D6@us.ibm.com>
On Mon, Nov 18, 2013 at 9:55 AM, David Stevens <dlstevens@us.ibm.com> wrote:
> 1) ICMP2BIG reflected from the tunnel endpoint without host routing and
> using the destination IP as the forged source address, thus
> appropriate
> for bridge-only hosting.
It doesn't look that existing icmp_send() can be hacked this way.
It cannot do route lookup and cannot do neigh lookup.
IPs and macs are valid within VM and known to virtualized networking
components, but
tunnel cannot possibly know what is standing between VM and tunnel.
VM may be sending over tap into a bridge that forwards into netns that
is running ip_fowarding
between two vethes, then goes into 2nd bridge and only then sent into
vxlan device.
ovs can do many actions before skb from tap is delivered to vport-vxlan.
The generic thing vxlan driver can do is to take mac and ip headers
from inner skb,
swap macs, swap ips, add icmphdr with code=frag_needed and pretend
that such packet
was received and decapsulated by vxlan, and call into vxlan_sock->rcv()
It will go back into ovs or bridge and will proceed through the
reverse network topology path all the way back into VM that can adjust
its mtu accordingly.
> 2) Allowing larger-than-gso_size segmentation as well as smaller when the
> final destination is on the virtual L2 network.
I think it should be ok for virtual L3 as well. From VM point of view,
it's sending 1500 byte packets and virtual routers/bridges on the path
to destination should check packets against their own mtu values. But
if tunneling infra is smart enough to use large frames between two
hypervisors,
it should do so. DF bit and pmtu logic applies within virtual
network, so sending icmp_frag_needed back into VM is exposing physical
infrastructure to virtual network.
True virtual distributed bridge with VMs should allow setting 8k mtu
inside VM and on the bridge and still function with 1500 mtu in the
underlying physical network.
^ permalink raw reply
* Re: [PATCH 2/2] ipv6: use sk_v6_copy_addrs when memcpy struct ipv6_pinfo
From: Eric Dumazet @ 2013-11-19 3:55 UTC (permalink / raw)
To: Wang Weidong
Cc: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, vyasevich,
nhorman, dccp, netdev, linux-sctp, dingtianhong
In-Reply-To: <1384829247-8624-3-git-send-email-wangweidong1@huawei.com>
On Tue, 2013-11-19 at 10:47 +0800, Wang Weidong wrote:
> commit efe4208f ("ipv6: make lookups simpler and faster") remove
> the daddr and rcv_saddr from struct ipv6_pinfo. When use memcpy
> the ipv6_pinfo, we lose the sk_v6_daddr and sk_v6_rcv_saddr, so
> use the sk_v6_copy_addrs when needed.
>
> Signed-off-by: Wang Weidong <wangweidong1@huawei.com>
> ---
> net/dccp/ipv6.c | 4 ++++
> net/ipv6/tcp_ipv6.c | 4 ++++
> net/sctp/ipv6.c | 4 ++++
> 3 files changed, 12 insertions(+)
>
> diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
> index 4ac71ff..90182a8 100644
> --- a/net/dccp/ipv6.c
> +++ b/net/dccp/ipv6.c
> @@ -465,6 +465,10 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
> newnp = inet6_sk(newsk);
>
> memcpy(newnp, np, sizeof(struct ipv6_pinfo));
> + /* Don't forget copy the rcv_saddr and daddr when
> + * copy ipv6_pinfo.
> + */
> + sk_v6_copy_addrs(newsk, sk);
>
> ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);
>
> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
> index 0740f93..83d011e 100644
> --- a/net/ipv6/tcp_ipv6.c
> +++ b/net/ipv6/tcp_ipv6.c
> @@ -1116,6 +1116,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
> newtp = tcp_sk(newsk);
>
> memcpy(newnp, np, sizeof(struct ipv6_pinfo));
> + /* Don't forget copy the rcv_saddr and daddr when
> + * copy ipv6_pinfo.
> + */
> + sk_v6_copy_addrs(newsk, sk);
>
> ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);
>
No idea why this patch is needed for TCP.
(btw you deal with v4mapped here, no mention of it in the changelog)
The fields were moved into generic socket, and generic socket is copied.
Are you seeing a real bug ?
Please elaborate, thanks !
^ permalink raw reply
* Re: [PATCH 2/2] ipv6: use sk_v6_copy_addrs when memcpy struct ipv6_pinfo
From: Eric Dumazet @ 2013-11-19 3:58 UTC (permalink / raw)
To: wangweidong
Cc: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, vyasevich,
nhorman, dccp, netdev, linux-sctp, dingtianhong
In-Reply-To: <528ADBDD.9040209@huawei.com>
On Tue, 2013-11-19 at 11:32 +0800, wangweidong wrote:
> On 2013/11/19 11:14, Hannes Frederic Sowa wrote:
> > On Tue, Nov 19, 2013 at 10:47:27AM +0800, Wang Weidong wrote:
> >> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
> >> index 0740f93..83d011e 100644
> >> --- a/net/ipv6/tcp_ipv6.c
> >> +++ b/net/ipv6/tcp_ipv6.c
> >> @@ -1116,6 +1116,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
> >> newtp = tcp_sk(newsk);
> >>
> >> memcpy(newnp, np, sizeof(struct ipv6_pinfo));
> >> + /* Don't forget copy the rcv_saddr and daddr when
> >> + * copy ipv6_pinfo.
> >> + */
> >> + sk_v6_copy_addrs(newsk, sk);
> >>
> >> ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);
> >>
> >
> > Hmm, how did you spot this?
> >
> > Greetings,
> >
> > Hannes
> >
>
> When I did the lksctp-tools(1.0.15)/src/func_tests/test_getname_v6, I got a Segmentation fault.
> So I try to resolve it. I found the sctp_accept will call sctp_v6_create_accept_sk in IPV6,
> the function will memcpy the ipv6_pinfo, and not copy the sk_v6_rcv_saddr. But the getsockname
> will read the sk_v6_rcv_saddr, and the value is not true.
But sctp is not tcp ;)
sctp_copy_sock() is doing some clever/partial copy of the socket, so
please fix it ;)
No idea why it's not doing the normal copy of the socket.
^ permalink raw reply
* Re: [PATCH 2/2] ipv6: use sk_v6_copy_addrs when memcpy struct ipv6_pinfo
From: Eric Dumazet @ 2013-11-19 4:00 UTC (permalink / raw)
To: wangweidong
Cc: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, vyasevich,
nhorman, dccp, netdev, linux-sctp, dingtianhong
In-Reply-To: <1384833538.8604.83.camel@edumazet-glaptop2.roam.corp.google.com>
On Mon, 2013-11-18 at 19:58 -0800, Eric Dumazet wrote:
> But sctp is not tcp ;)
>
> sctp_copy_sock() is doing some clever/partial copy of the socket, so
> please fix it ;)
>
> No idea why it's not doing the normal copy of the socket.
BTW, not doing the full copy means for example that SO_MAX_PACING_RATE
is broken for SCTP.
^ permalink raw reply
* Re: [PATCH 2/2] ipv6: use sk_v6_copy_addrs when memcpy struct ipv6_pinfo
From: wangweidong @ 2013-11-19 4:38 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, vyasevich,
nhorman, dccp, netdev, linux-sctp, dingtianhong
In-Reply-To: <1384833303.8604.81.camel@edumazet-glaptop2.roam.corp.google.com>
On 2013/11/19 11:55, Eric Dumazet wrote:
> On Tue, 2013-11-19 at 10:47 +0800, Wang Weidong wrote:
>> commit efe4208f ("ipv6: make lookups simpler and faster") remove
>> the daddr and rcv_saddr from struct ipv6_pinfo. When use memcpy
>> the ipv6_pinfo, we lose the sk_v6_daddr and sk_v6_rcv_saddr, so
>> use the sk_v6_copy_addrs when needed.
>>
>> Signed-off-by: Wang Weidong <wangweidong1@huawei.com>
>> ---
>> net/dccp/ipv6.c | 4 ++++
>> net/ipv6/tcp_ipv6.c | 4 ++++
>> net/sctp/ipv6.c | 4 ++++
>> 3 files changed, 12 insertions(+)
>>
>> diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
>> index 4ac71ff..90182a8 100644
>> --- a/net/dccp/ipv6.c
>> +++ b/net/dccp/ipv6.c
>> @@ -465,6 +465,10 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
>> newnp = inet6_sk(newsk);
>>
>> memcpy(newnp, np, sizeof(struct ipv6_pinfo));
>> + /* Don't forget copy the rcv_saddr and daddr when
>> + * copy ipv6_pinfo.
>> + */
>> + sk_v6_copy_addrs(newsk, sk);
>>
>> ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);
>>
>> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
>> index 0740f93..83d011e 100644
>> --- a/net/ipv6/tcp_ipv6.c
>> +++ b/net/ipv6/tcp_ipv6.c
>> @@ -1116,6 +1116,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
>> newtp = tcp_sk(newsk);
>>
>> memcpy(newnp, np, sizeof(struct ipv6_pinfo));
>> + /* Don't forget copy the rcv_saddr and daddr when
>> + * copy ipv6_pinfo.
>> + */
>> + sk_v6_copy_addrs(newsk, sk);
>>
>> ipv6_addr_set_v4mapped(newinet->inet_daddr, &newsk->sk_v6_daddr);
>>
>
>
> No idea why this patch is needed for TCP.
> (btw you deal with v4mapped here, no mention of it in the changelog)
>
> The fields were moved into generic socket, and generic socket is copied.
>
> Are you seeing a real bug ?
>
> Please elaborate, thanks !
>
Hm, You are right. I am not careful to look over the generic socket whether it would be
copied. Sorry for that.
Thanks.
>
>
>
>
^ permalink raw reply
* Re: [PATCH 2/2] ipv6: use sk_v6_copy_addrs when memcpy struct ipv6_pinfo
From: wangweidong @ 2013-11-19 4:44 UTC (permalink / raw)
To: Eric Dumazet
Cc: davem, gerrit, kuznet, jmorris, yoshfuji, kaber, vyasevich,
nhorman, dccp, netdev, linux-sctp, dingtianhong
In-Reply-To: <1384833653.8604.84.camel@edumazet-glaptop2.roam.corp.google.com>
On 2013/11/19 12:00, Eric Dumazet wrote:
> On Mon, 2013-11-18 at 19:58 -0800, Eric Dumazet wrote:
>
>> But sctp is not tcp ;)
>>
>> sctp_copy_sock() is doing some clever/partial copy of the socket, so
>> please fix it ;)
>>
>> No idea why it's not doing the normal copy of the socket.
>
> BTW, not doing the full copy means for example that SO_MAX_PACING_RATE
> is broken for SCTP.
>
>
>
The dccp will copy the geniric socket, too. And You mean to say that only
add the copies in sctp_copy_sock().
Thanks.
>
>
>
>
^ permalink raw reply
* Re: [PATCH RFC 0/9]net: stmmac PM related fixes.
From: Giuseppe CAVALLARO @ 2013-11-19 5:24 UTC (permalink / raw)
To: srinivas.kandagatla; +Cc: netdev, linux-kernel
In-Reply-To: <1384774256-10039-1-git-send-email-srinivas.kandagatla@st.com>
On 11/18/2013 12:30 PM, srinivas.kandagatla@st.com wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>
> Hi Peppe,
>
> During PM_SUSPEND_FREEZE testing, I have noticed that PM support in STMMAC is
> partly broken. I had to re-arrange the code to do PM correctly. There were lot
> of things I did not like personally and some bits did not work in the first
> place. I thought this is the nice opportunity to clean the mess up.
>
> Here is what I did:
>
> 1> Test PM suspend freeeze via pm_test
> It did not work for following reasons.
> - If the power to gmac is removed when it enters in low power state.
> stmmac_resume could not cope up with such behaviour, it was expecting the ip
> register contents to be still same as before entering low power, This
> assumption is wrong. So I started to add some code to do Hardware
> initialization, thats when I started to re-arrange the code. stmmac_open
> contains both resource and memory allocations and hardware initialization. I
> had to separate these two things in two different functions.
>
> These two patches do that
> net: stmmac: move dma allocation to new function
> net: stmmac: move hardware setup for stmmac_open to new function
>
> And rest of the other patches are fixing the loose ends, things like mdio
> reset, which might be necessary in cases likes hibernation(I did not test).
>
> In hibernation cases the driver was just unregistering with subsystems and
> releasing resources which I did not like and its not necessary to do this as
> part of PM. So using the same stmmac_suspend/resume made more sense for
> hibernation cases than using stmmac_open/release.
> Also fixed a NULL pointer dereference bug too.
>
> 2> Test WOL via PM_SUSPEND_FREEZE
> Did get an wakeup interrupt, but could not wakeup a freeze system.
> So I had to add pm_wakeup_event to the driver.
> net: stmmac: notify the PM core of a wakeup event. patch.
>
> Also few patches like
> net: stmmac: make stmmac_mdio_reset non-static
> net: stmmac: restore pinstate in pm resume.
> helps the resume function to reset the phy and put back the pins in default
> state.
>
> Comments?
Srini, as we had internally discussed before sending the patches to the
net ML, I agreed with your work. Some parts of the PM stuff was fully
tested on our product kernels (where the PM was a bit different
especially on HoM) and nobody raised issues to me for this code.
Also some rework you did, for example to move the dma allocation in
a new function is fine for me.
So you continue to have my Acked-by for all.
peppe
>
> Thanks,
> srini
>
> Srinivas Kandagatla (9):
> net: stmmac: support max-speed device tree property
> net: stmmac: mdio: remove reset gpio free
> net: stmmac: move dma allocation to new function
> net: stmmac: move hardware setup for stmmac_open to new function
> net: stmmac: make stmmac_mdio_reset non-static
> net: stmmac: fix power mangement suspend-resume case
> net: stmmac: use suspend functions for hibernation
> net: stmmac: restore pinstate in pm resume.
> net: stmmac: notify the PM core of a wakeup event.
>
> drivers/net/ethernet/stmicro/stmmac/stmmac.h | 4 +-
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 360 ++++++++++----------
> drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 3 +-
> .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 51 +--
> include/linux/stmmac.h | 1 +
> 5 files changed, 209 insertions(+), 210 deletions(-)
>
^ permalink raw reply
* Re: [PATCH net 4/6] stmmac: Validate hwtstamp_config completely before applying it
From: Giuseppe CAVALLARO @ 2013-11-19 5:26 UTC (permalink / raw)
To: Ben Hutchings, Rayagond K; +Cc: David Miller, netdev, Richard Cochran
In-Reply-To: <1384389821.29151.10.camel@bwh-desktop.uk.level5networks.com>
On 11/14/2013 1:44 AM, Ben Hutchings wrote:
> stmmac_hwtstamp_ioctl() should validate all fields of hwtstamp_config
> before making any changes. Currently it sets the TX configuration
> before validating the rx_filter field.
>
> Compile-tested only.
Thx Ben for this patch.
Rayagond, can you do any run-time tests?
peppe
>
> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 12 +++---------
> 1 file changed, 3 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 8d4ccd35a016..8a7a23a84ac5 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -435,16 +435,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
> if (config.flags)
> return -EINVAL;
>
> - switch (config.tx_type) {
> - case HWTSTAMP_TX_OFF:
> - priv->hwts_tx_en = 0;
> - break;
> - case HWTSTAMP_TX_ON:
> - priv->hwts_tx_en = 1;
> - break;
> - default:
> + if (config.tx_type != HWTSTAMP_TX_OFF &&
> + config.tx_type != HWTSTAMP_TX_ON)
> return -ERANGE;
> - }
>
> if (priv->adv_ts) {
> switch (config.rx_filter) {
> @@ -576,6 +569,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
> }
> }
> priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0 : 1);
> + priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
>
> if (!priv->hwts_tx_en && !priv->hwts_rx_en)
> priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0);
>
>
^ permalink raw reply
* [PATCH RFC] net: rework recvmsg handler msg_name and msg_namelen logic
From: Hannes Frederic Sowa @ 2013-11-19 5:27 UTC (permalink / raw)
To: netdev
This patch now always passes msg->msg_namelen as 0. recvmsg handlers must
set msg_namelen to the proper size <= sizeof(struct sockaddr_storage)
to return msg_name to the user.
This prevents numerous uninitialized memory leaks we had in the
recvmsg handlers and makes it harder for new code to accidentally leak
uninitialized memory.
Optimize for the case recvfrom is called with NULL as address. We don't
need to copy the address at all, so set it to NULL before invoking the
recvmsg handler. We can do so, because all the recvmsg handlers must
cope with the case a plain read() is called on them. read() also sets
msg_name to NULL.
Also document these changes in include/linux/net.h as suggested by David
Miller.
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
crypto/algif_hash.c | 2 --
crypto/algif_skcipher.c | 1 -
drivers/isdn/mISDN/socket.c | 14 +++++---------
drivers/net/ppp/pppoe.c | 2 --
include/linux/net.h | 8 ++++++++
net/appletalk/ddp.c | 17 ++++++++---------
net/atm/common.c | 2 --
net/ax25/af_ax25.c | 5 +++--
net/bluetooth/af_bluetooth.c | 9 ++-------
net/bluetooth/hci_sock.c | 2 --
net/bluetooth/rfcomm/sock.c | 1 -
net/bluetooth/sco.c | 1 -
net/caif/caif_socket.c | 4 ----
net/ipx/af_ipx.c | 3 +--
net/irda/af_irda.c | 4 ----
net/iucv/af_iucv.c | 2 --
net/key/af_key.c | 1 -
net/l2tp/l2tp_ppp.c | 2 --
net/llc/af_llc.c | 2 --
net/netlink/af_netlink.c | 2 --
net/netrom/af_netrom.c | 3 +--
net/nfc/llcp_sock.c | 2 --
net/nfc/rawsock.c | 2 --
net/packet/af_packet.c | 32 +++++++++++++++-----------------
net/rds/recv.c | 2 --
net/rose/af_rose.c | 8 +++++---
net/rxrpc/ar-recvmsg.c | 9 ++++++---
net/socket.c | 12 ++++++++++--
net/tipc/socket.c | 6 ------
net/unix/af_unix.c | 5 -----
net/vmw_vsock/af_vsock.c | 2 --
net/vmw_vsock/vmci_transport.c | 2 --
net/x25/af_x25.c | 3 +--
33 files changed, 65 insertions(+), 107 deletions(-)
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c
index 0262210..ef5356c 100644
--- a/crypto/algif_hash.c
+++ b/crypto/algif_hash.c
@@ -161,8 +161,6 @@ static int hash_recvmsg(struct kiocb *unused, struct socket *sock,
else if (len < ds)
msg->msg_flags |= MSG_TRUNC;
- msg->msg_namelen = 0;
-
lock_sock(sk);
if (ctx->more) {
ctx->more = 0;
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
index a1c4f0a..6a6dfc0 100644
--- a/crypto/algif_skcipher.c
+++ b/crypto/algif_skcipher.c
@@ -432,7 +432,6 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock,
long copied = 0;
lock_sock(sk);
- msg->msg_namelen = 0;
for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0;
iovlen--, iov++) {
unsigned long seglen = iov->iov_len;
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c
index e47dcb9..f31c17c 100644
--- a/drivers/isdn/mISDN/socket.c
+++ b/drivers/isdn/mISDN/socket.c
@@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
{
struct sk_buff *skb;
struct sock *sk = sock->sk;
- struct sockaddr_mISDN *maddr;
int copied, err;
@@ -135,9 +134,10 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
return err;
- if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
- msg->msg_namelen = sizeof(struct sockaddr_mISDN);
- maddr = (struct sockaddr_mISDN *)msg->msg_name;
+ if (msg->msg_name) {
+ struct sockaddr_mISDN *maddr =
+ (struct sockaddr_mISDN *)msg->msg_name;
+
maddr->family = AF_ISDN;
maddr->dev = _pms(sk)->dev->id;
if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
@@ -150,11 +150,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
maddr->sapi = _pms(sk)->ch.addr & 0xFF;
maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF;
}
- } else {
- if (msg->msg_namelen)
- printk(KERN_WARNING "%s: too small namelen %d\n",
- __func__, msg->msg_namelen);
- msg->msg_namelen = 0;
+ msg->msg_namelen = sizeof(*maddr);
}
copied = skb->len + MISDN_HEADER_LEN;
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 5f66e30..82ee6ed 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -979,8 +979,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
if (error < 0)
goto end;
- m->msg_namelen = 0;
-
if (skb) {
total_len = min_t(size_t, total_len, skb->len);
error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
diff --git a/include/linux/net.h b/include/linux/net.h
index b292a04..4bcee94 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -164,6 +164,14 @@ struct proto_ops {
#endif
int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len);
+ /* Notes for implementing recvmsg:
+ * ===============================
+ * msg->msg_namelen should get updated by the recvmsg handlers
+ * iff msg_name != NULL. It is by default 0 to prevent
+ * returning uninitialized memory to user space. The recvfrom
+ * handlers can assume that msg.msg_name is either NULL or has
+ * a minimum size of sizeof(struct sockaddr_storage).
+ */
int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len,
int flags);
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 7fee50d..20f6e3b 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1735,7 +1735,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
size_t size, int flags)
{
struct sock *sk = sock->sk;
- struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
struct ddpehdr *ddp;
int copied = 0;
int offset = 0;
@@ -1764,14 +1763,14 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
}
err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
- if (!err) {
- if (sat) {
- sat->sat_family = AF_APPLETALK;
- sat->sat_port = ddp->deh_sport;
- sat->sat_addr.s_node = ddp->deh_snode;
- sat->sat_addr.s_net = ddp->deh_snet;
- }
- msg->msg_namelen = sizeof(*sat);
+ if (!err && msg->msg_name) {
+ struct sockaddr_at *sat =
+ (struct sockaddr_at *)msg->msg_name;
+ sat->sat_family = AF_APPLETALK;
+ sat->sat_port = ddp->deh_sport;
+ sat->sat_addr.s_node = ddp->deh_snode;
+ sat->sat_addr.s_net = ddp->deh_snet;
+ msg->msg_namelen = sizeof(*sat);
}
skb_free_datagram(sk, skb); /* Free the datagram. */
diff --git a/net/atm/common.c b/net/atm/common.c
index 737bef5..7b49100 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -531,8 +531,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
struct sk_buff *skb;
int copied, error = -EINVAL;
- msg->msg_namelen = 0;
-
if (sock->state != SS_CONNECTED)
return -ENOTCONN;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index a00123e..b64aea5 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1636,11 +1636,12 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
- if (msg->msg_namelen != 0) {
- struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name;
+ if (msg->msg_name) {
ax25_digi digi;
ax25_address src;
const unsigned char *mac = skb_mac_header(skb);
+ struct sockaddr_ax25 *sax =
+ (struct sockaddr_ax25 *)msg->msg_name;
memset(sax, 0, sizeof(struct full_sockaddr_ax25));
ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index f6a1671..56ca494 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -224,10 +224,9 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) {
- if (sk->sk_shutdown & RCV_SHUTDOWN) {
- msg->msg_namelen = 0;
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
return 0;
- }
+
return err;
}
@@ -245,8 +244,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (bt_sk(sk)->skb_msg_name)
bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
&msg->msg_namelen);
- else
- msg->msg_namelen = 0;
}
skb_free_datagram(sk, skb);
@@ -295,8 +292,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags & MSG_OOB)
return -EOPNOTSUPP;
- msg->msg_namelen = 0;
-
BT_DBG("sk %p size %zu", sk, size);
lock_sock(sk);
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 71f0be1..6a6c8bb 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -856,8 +856,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
return err;
- msg->msg_namelen = 0;
-
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index c4d3d42..c80766f 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -615,7 +615,6 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
- msg->msg_namelen = 0;
return 0;
}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 12a0e51..24fa396 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -711,7 +711,6 @@ static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
sco_conn_defer_accept(pi->conn->hcon, pi->setting);
sk->sk_state = BT_CONFIG;
- msg->msg_namelen = 0;
release_sock(sk);
return 0;
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c
index 05a41c7..d6be3ed 100644
--- a/net/caif/caif_socket.c
+++ b/net/caif/caif_socket.c
@@ -286,8 +286,6 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock,
if (m->msg_flags&MSG_OOB)
goto read_error;
- m->msg_namelen = 0;
-
skb = skb_recv_datagram(sk, flags, 0 , &ret);
if (!skb)
goto read_error;
@@ -361,8 +359,6 @@ static int caif_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags&MSG_OOB)
goto out;
- msg->msg_namelen = 0;
-
/*
* Lock the socket to prevent queue disordering
* while sleeps in memcpy_tomsg
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 7a1e0fc..e096025 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -1823,8 +1823,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
if (skb->tstamp.tv64)
sk->sk_stamp = skb->tstamp;
- msg->msg_namelen = sizeof(*sipx);
-
if (sipx) {
sipx->sipx_family = AF_IPX;
sipx->sipx_port = ipx->ipx_source.sock;
@@ -1832,6 +1830,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net;
sipx->sipx_type = ipx->ipx_type;
sipx->sipx_zero = 0;
+ msg->msg_namelen = sizeof(*sipx);
}
rc = copied;
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 0f67690..de7db23 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1385,8 +1385,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
IRDA_DEBUG(4, "%s()\n", __func__);
- msg->msg_namelen = 0;
-
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
if (!skb)
@@ -1451,8 +1449,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
timeo = sock_rcvtimeo(sk, noblock);
- msg->msg_namelen = 0;
-
do {
int chunk;
struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 168aff5..c4b7218 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1324,8 +1324,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
int err = 0;
u32 offset;
- msg->msg_namelen = 0;
-
if ((sk->sk_state == IUCV_DISCONN) &&
skb_queue_empty(&iucv->backlog_skb_q) &&
skb_queue_empty(&sk->sk_receive_queue) &&
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 911ef03..545f047 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3616,7 +3616,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
goto out;
- msg->msg_namelen = 0;
skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
if (skb == NULL)
goto out;
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index ffda81e..be5fadf 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -197,8 +197,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
if (sk->sk_state & PPPOX_BOUND)
goto end;
- msg->msg_namelen = 0;
-
err = 0;
skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
flags & MSG_DONTWAIT, &err);
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 6cba486..7b01b9f 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -720,8 +720,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
int target; /* Read at least this many bytes */
long timeo;
- msg->msg_namelen = 0;
-
lock_sock(sk);
copied = -ENOTCONN;
if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 8df7f64..6135635 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2335,8 +2335,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
}
#endif
- msg->msg_namelen = 0;
-
copied = data_skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 698814b..53c19a3 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1179,10 +1179,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
sax->sax25_family = AF_NETROM;
skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
AX25_ADDR_LEN);
+ msg->msg_namelen = sizeof(*sax);
}
- msg->msg_namelen = sizeof(*sax);
-
skb_free_datagram(sk, skb);
release_sock(sk);
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index d308402..824c605 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -807,8 +807,6 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
pr_debug("%p %zu\n", sk, len);
- msg->msg_namelen = 0;
-
lock_sock(sk);
if (sk->sk_state == LLCP_CLOSED &&
diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c
index cd958b3..66bcd2e 100644
--- a/net/nfc/rawsock.c
+++ b/net/nfc/rawsock.c
@@ -244,8 +244,6 @@ static int rawsock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
return rc;
- msg->msg_namelen = 0;
-
copied = skb->len;
if (len < copied) {
msg->msg_flags |= MSG_TRUNC;
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2e8286b..61bd50a 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2660,7 +2660,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk;
struct sk_buff *skb;
int copied, err;
- struct sockaddr_ll *sll;
int vnet_hdr_len = 0;
err = -EINVAL;
@@ -2744,22 +2743,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
goto out_free;
}
- /*
- * If the address length field is there to be filled in, we fill
- * it in now.
- */
-
- sll = &PACKET_SKB_CB(skb)->sa.ll;
- if (sock->type == SOCK_PACKET)
- msg->msg_namelen = sizeof(struct sockaddr_pkt);
- else
- msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
-
- /*
- * You lose any data beyond the buffer you gave. If it worries a
- * user program they can ask the device for its MTU anyway.
+ /* You lose any data beyond the buffer you gave. If it worries
+ * a user program they can ask the device for its MTU
+ * anyway.
*/
-
copied = skb->len;
if (copied > len) {
copied = len;
@@ -2772,9 +2759,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
sock_recv_ts_and_drops(msg, sk, skb);
- if (msg->msg_name)
+ if (msg->msg_name) {
+ /* If the address length field is there to be filled
+ * in, we fill it in now.
+ */
+ if (sock->type == SOCK_PACKET) {
+ msg->msg_namelen = sizeof(struct sockaddr_pkt);
+ } else {
+ struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
+ msg->msg_namelen = sll->sll_halen +
+ offsetof(struct sockaddr_ll, sll_addr);
+ }
memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
msg->msg_namelen);
+ }
if (pkt_sk(sk)->auxdata) {
struct tpacket_auxdata aux;
diff --git a/net/rds/recv.c b/net/rds/recv.c
index 9f0f17c..de339b2 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
- msg->msg_namelen = 0;
-
if (msg_flags & MSG_OOB)
goto out;
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index e98fcfb..2b491bf 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1216,7 +1216,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
{
struct sock *sk = sock->sk;
struct rose_sock *rose = rose_sk(sk);
- struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
size_t copied;
unsigned char *asmptr;
struct sk_buff *skb;
@@ -1252,8 +1251,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
- if (srose != NULL) {
- memset(srose, 0, msg->msg_namelen);
+ if (msg->msg_name) {
+ struct sockaddr_rose *srose;
+
+ memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
+ srose = (struct sockaddr_rose *)msg->msg_name;
srose->srose_family = AF_ROSE;
srose->srose_addr = rose->dest_addr;
srose->srose_call = rose->dest_call;
diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c
index 4b48687..898492a 100644
--- a/net/rxrpc/ar-recvmsg.c
+++ b/net/rxrpc/ar-recvmsg.c
@@ -143,10 +143,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
/* copy the peer address and timestamp */
if (!continue_call) {
- if (msg->msg_name && msg->msg_namelen > 0)
+ if (msg->msg_name) {
+ size_t len =
+ sizeof(call->conn->trans->peer->srx);
memcpy(msg->msg_name,
- &call->conn->trans->peer->srx,
- sizeof(call->conn->trans->peer->srx));
+ &call->conn->trans->peer->srx, len);
+ msg->msg_namelen = len;
+ }
sock_recv_ts_and_drops(msg, &rx->sk, skb);
}
diff --git a/net/socket.c b/net/socket.c
index c226ace..69f7a9d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1840,8 +1840,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
msg.msg_iov = &iov;
iov.iov_len = size;
iov.iov_base = ubuf;
- msg.msg_name = (struct sockaddr *)&address;
- msg.msg_namelen = sizeof(address);
+ /* Save some cycles and don't copy the address if not needed */
+ msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
+ /* We assume all kernel code knows the size of sockaddr_storage */
+ msg.msg_namelen = 0;
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
err = sock_recvmsg(sock, &msg, size, flags);
@@ -2239,6 +2241,12 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
cmsg_ptr = (unsigned long)msg_sys->msg_control;
msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
+ /* Save some cycles and don't copy the address if not needed */
+ if (!uaddr || msg_sys->msg_namelen == 0)
+ msg_sys->msg_name = NULL;
+ /* We assume all kernel code knows the size of sockaddr_storage */
+ msg_sys->msg_namelen = 0;
+
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;
err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys,
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 3906527..3b61851 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -980,9 +980,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
goto exit;
}
- /* will be updated in set_orig_addr() if needed */
- m->msg_namelen = 0;
-
timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
restart:
@@ -1091,9 +1088,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
goto exit;
}
- /* will be updated in set_orig_addr() if needed */
- m->msg_namelen = 0;
-
target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len);
timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index c1f403b..01625cc 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1754,7 +1754,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{
struct unix_sock *u = unix_sk(sk);
- msg->msg_namelen = 0;
if (u->addr) {
msg->msg_namelen = u->addr->len;
memcpy(msg->msg_name, u->addr->name, u->addr->len);
@@ -1778,8 +1777,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags&MSG_OOB)
goto out;
- msg->msg_namelen = 0;
-
err = mutex_lock_interruptible(&u->readlock);
if (err) {
err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
@@ -1924,8 +1921,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
- msg->msg_namelen = 0;
-
/* Lock the socket to prevent queue disordering
* while sleeps in memcpy_tomsg
*/
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 545c08b..5adfd94 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1662,8 +1662,6 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
vsk = vsock_sk(sk);
err = 0;
- msg->msg_namelen = 0;
-
lock_sock(sk);
if (sk->sk_state != SS_CONNECTED) {
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 9d69866..687360d 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -1746,8 +1746,6 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
if (flags & MSG_OOB || flags & MSG_ERRQUEUE)
return -EOPNOTSUPP;
- msg->msg_namelen = 0;
-
/* Retrieve the head sk_buff from the socket's receive queue. */
err = 0;
skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err);
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 45a3ab5..7622789 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -1340,10 +1340,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
if (sx25) {
sx25->sx25_family = AF_X25;
sx25->sx25_addr = x25->dest_addr;
+ msg->msg_namelen = sizeof(*sx25);
}
- msg->msg_namelen = sizeof(struct sockaddr_x25);
-
x25_check_rbuf(sk);
rc = copied;
out_free_dgram:
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH RFC 00/10] ARM: STi: Add dwmac glue and reset controller
From: Giuseppe CAVALLARO @ 2013-11-19 5:28 UTC (permalink / raw)
To: srinivas.kandagatla
Cc: linux-arm-kernel, netdev, Rob Herring, Pawel Moll, Mark Rutland,
Stephen Warren, Ian Campbell, Rob Landley, Russell King,
Stuart Menefy, Pavel Machek, Rafael J. Wysocki, Len Brown,
Greg Kroah-Hartman, Grant Likely, devicetree, linux-doc,
stephen.gallimore, linux-kernel, kernel, linux-pm
In-Reply-To: <1384264311-7308-1-git-send-email-srinivas.kandagatla@st.com>
On 11/12/2013 2:51 PM, srinivas.kandagatla@st.com wrote:
> From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>
> Hi All,
>
> This patch series adds Ethernet support to STi series SOCs STiH415 and STiH416.
> STi SOC series integrates dwmac IP from synopsis, however there is a hardware
> glue on top of this standard IP, this glue needs to configured before the
> actual dwmac can be used.
> To add this a new driver dwmac-sti is introduced whose responsibility is to
> configure dwmac glue and before dwmac driver, this is achieved by making dwmac
> device node as child to ethernet glue node. Inspired by usb/dwc3.
> Also the glue needs to come out of softreset which is why we have added a
> softreset controller to driver which looked perfectly neat, rather then
> driving the softreset bit from the glue driver.
>
> Also as part of power management in glue driver, I found that there was no
> function to determine if the child device is a wakeup source or not.
> I have added a new api device_child_may_wakeup API which could be useful for
> drivers like this. "PM / wakeup : Introduce device_child_may_wakeup" patch has
> that new API and "net: stmmac:sti: Add STi SOC glue driver." glue driver uses
> this new API.
>
> The reason for combining all these patches in a same series is because of
> dependencies.
>
> This patch series is tested on B2000 and B2020 boards with STiH415, STiH416
> SOC on ethernet 100/1000 Links.
>
> Comments?
Hello Srini
ll these patches are ok for me and, as you know, I have already started
using them while porting other SoC. Glue logic is mandatory now!
Thanks
peppe
>
> Thanks,
> srini
>
> Srinivas Kandagatla (6):
> drivers: reset: stih415: add softreset controller
> drivers: reset: stih416: add softreset controller
> PM / wakeup : Introduce device_child_may_wakeup
> net: stmmac:sti: Add STi SOC glue driver.
> ARM: STi: Add STiH415 ethernet support.
> ARM: STi: Add STiH416 ethernet support.
>
> Stephen Gallimore (4):
> drivers: reset: STi SoC system configuration reset controller support
> drivers: reset: Reset controller driver for STiH415
> drivers: reset: Reset controller driver for STiH416
> ARM: STi: Add reset controller support to mach-sti Kconfig
>
> .../devicetree/bindings/net/sti-dwmac.txt | 45 +++
> .../devicetree/bindings/reset/st,sti-powerdown.txt | 46 +++
> .../devicetree/bindings/reset/st,sti-softreset.txt | 45 +++
> arch/arm/boot/dts/stih415-clock.dtsi | 14 +
> arch/arm/boot/dts/stih415-pinctrl.dtsi | 82 ++++++
> arch/arm/boot/dts/stih415.dtsi | 67 +++++
> arch/arm/boot/dts/stih416-clock.dtsi | 14 +
> arch/arm/boot/dts/stih416-pinctrl.dtsi | 106 +++++++
> arch/arm/boot/dts/stih416.dtsi | 69 +++++
> arch/arm/boot/dts/stih41x-b2000.dtsi | 32 +++
> arch/arm/boot/dts/stih41x-b2020.dtsi | 33 +++
> arch/arm/mach-sti/Kconfig | 3 +
> drivers/base/power/wakeup.c | 23 ++
> drivers/net/ethernet/stmicro/stmmac/Makefile | 1 +
> drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c | 294 ++++++++++++++++++++
> drivers/reset/Kconfig | 2 +
> drivers/reset/Makefile | 3 +
> drivers/reset/sti/Kconfig | 15 +
> drivers/reset/sti/Makefile | 4 +
> drivers/reset/sti/reset-stih415.c | 99 +++++++
> drivers/reset/sti/reset-stih416.c | 101 +++++++
> drivers/reset/sti/reset-syscfg.c | 186 ++++++++++++
> drivers/reset/sti/reset-syscfg.h | 69 +++++
> .../dt-bindings/reset-controller/stih415-resets.h | 23 ++
> .../dt-bindings/reset-controller/stih416-resets.h | 25 ++
> include/linux/pm_wakeup.h | 1 +
> 26 files changed, 1402 insertions(+), 0 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/net/sti-dwmac.txt
> create mode 100644 Documentation/devicetree/bindings/reset/st,sti-powerdown.txt
> create mode 100644 Documentation/devicetree/bindings/reset/st,sti-softreset.txt
> create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
> create mode 100644 drivers/reset/sti/Kconfig
> create mode 100644 drivers/reset/sti/Makefile
> create mode 100644 drivers/reset/sti/reset-stih415.c
> create mode 100644 drivers/reset/sti/reset-stih416.c
> create mode 100644 drivers/reset/sti/reset-syscfg.c
> create mode 100644 drivers/reset/sti/reset-syscfg.h
> create mode 100644 include/dt-bindings/reset-controller/stih415-resets.h
> create mode 100644 include/dt-bindings/reset-controller/stih416-resets.h
>
^ permalink raw reply
* Re: [PATCH net 4/6] stmmac: Validate hwtstamp_config completely before applying it
From: Rayagond K @ 2013-11-19 5:55 UTC (permalink / raw)
To: Giuseppe CAVALLARO; +Cc: Ben Hutchings, David Miller, netdev, Richard Cochran
In-Reply-To: <528AF66F.2060204@st.com>
On Tue, Nov 19, 2013 at 10:56 AM, Giuseppe CAVALLARO
<peppe.cavallaro@st.com> wrote:
> On 11/14/2013 1:44 AM, Ben Hutchings wrote:
>>
>> stmmac_hwtstamp_ioctl() should validate all fields of hwtstamp_config
>> before making any changes. Currently it sets the TX configuration
>> before validating the rx_filter field.
>>
>> Compile-tested only.
>
>
> Thx Ben for this patch.
>
> Rayagond, can you do any run-time tests?
I don't have HW now. But next week I will be getting GMAC 4.0, so I
can do similar changes in that driver and do run-time test.
>
> peppe
>
>
>>
>> Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
>> ---
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 12 +++---------
>> 1 file changed, 3 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index 8d4ccd35a016..8a7a23a84ac5 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -435,16 +435,9 @@ static int stmmac_hwtstamp_ioctl(struct net_device
>> *dev, struct ifreq *ifr)
>> if (config.flags)
>> return -EINVAL;
>>
>> - switch (config.tx_type) {
>> - case HWTSTAMP_TX_OFF:
>> - priv->hwts_tx_en = 0;
>> - break;
>> - case HWTSTAMP_TX_ON:
>> - priv->hwts_tx_en = 1;
>> - break;
>> - default:
>> + if (config.tx_type != HWTSTAMP_TX_OFF &&
>> + config.tx_type != HWTSTAMP_TX_ON)
>> return -ERANGE;
>> - }
>>
>> if (priv->adv_ts) {
>> switch (config.rx_filter) {
>> @@ -576,6 +569,7 @@ static int stmmac_hwtstamp_ioctl(struct net_device
>> *dev, struct ifreq *ifr)
>> }
>> }
>> priv->hwts_rx_en = ((config.rx_filter == HWTSTAMP_FILTER_NONE) ? 0
>> : 1);
>> + priv->hwts_tx_en = config.tx_type == HWTSTAMP_TX_ON;
>>
>> if (!priv->hwts_tx_en && !priv->hwts_rx_en)
>> priv->hw->ptp->config_hw_tstamping(priv->ioaddr, 0);
>>
>>
>
^ permalink raw reply
* Re: [PATCH net v2 1/2] net: sched: tbf: fix calculation of max_size
From: Yang Yingliang @ 2013-11-19 6:04 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: davem, netdev, eric.dumazet, brouer, jpirko
In-Reply-To: <20131118133246.02651392@redhat.com>
On 2013/11/18 20:32, Jesper Dangaard Brouer wrote:
> On Mon, 18 Nov 2013 16:39:23 +0800
> Yang Yingliang <yangyingliang@huawei.com> wrote:
>
>> commit b757c9336d63f94c6b57532(tbf: improved accuracy at high rates)
>> introduce a regression.
>>
>> With the follow command:
>> tc qdisc add dev eth1 root handle 1: tbf latency 50ms burst 10KB rate 30gbit mtu 64k
>>
>> Without this patch, the max_size value is 10751(bytes).
>> But, in fact, the real max_size value should be smaller than 7440(bytes).
>> Or a packet whose length is bigger than 7440 will cause network congestion.
>> Because the packet is so big that can't get enough tokens. Even all the tokens
>> in the buffer is given to the packet.
>>
>> With this patch, the max_size value is 7440(bytes).
>> The packets whose length is bigger than 7440(bytes) will be dropped or reshape
>> in tbf_enqueue().
>
>
> I acknowledge that TBF seems to have some dependencies to the
> userspace constructed rate table (which we do NOT use anymore in the
> kernel). And that these should be fixed.
>
> But I'm not sure that your patch is the best solution... and the patch
> also contains some issues, see inlined comments.
>
> The main annoying problem is *again* how the rate table system got
> removed, in the kernel, but nobody fixed userspace.
>
>
> So, the main problem is that qopt->buffer (send from userspace/tc) is
> in a "time-format" (user input "burst" in bytes). Which used-to, make
> sense because the rate table used the same "time-format".
>
> Now you are reversing this calculation of "q->buffer" (token burst)
> back into bytes, so we can choose "max_size" (to avoid a problem in
> tbf_dequeue()).
>
> I don't like this converting back-and-forth, I'm worried about
> rounding errors.
>
> The easiest "hack" solution would be:
>
> for (n = 0; n < 65535; n++)
> if (psched_l2t_ns(&qopt->rate, n) > q->buffer)
> break;
> max_size = n;
>
> Unfortunately we have to keep backward compat with iproute2/tc, but
> IMHO it would be a lot easier, if we could fix userspace, and remove
> all the length-to-time calculations, as they should now be the
> responsibility of the kernel. Well, wishful thinking...
>
>
>
>> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
>> ---
>> include/net/sch_generic.h | 46 ++++++++++++++++++++++++++++++++
>> net/sched/sch_tbf.c | 67 ++++++++++++++++++++++++++---------------------
>> 2 files changed, 83 insertions(+), 30 deletions(-)
>>
>> diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
>> index d0a6321..8da64f3 100644
>> --- a/include/net/sch_generic.h
>> +++ b/include/net/sch_generic.h
>> @@ -701,6 +701,52 @@ static inline u64 psched_l2t_ns(const struct psched_ratecfg *r,
>> return ((u64)len * r->mult) >> r->shift;
>> }
>>
>> +/* Time to Length, convert time in ns to length in bytes
>> + * to determinate how many bytes can be sent in given time.
>> + */
>> +static inline u64 psched_ns_t2l(const struct psched_ratecfg *r,
>> + u64 time_in_ns)
>> +{
>> + u64 len = time_in_ns;
>> + u8 shift = r->shift;
>> + bool is_div = false;
>> +
>> + /* The formula is :
>> + * len = (time_in_ns << shift) / mult
>> + * when time_in_ns does shift, it would overflow.
>> + * If overflow happens first time, do division.
>> + * Then do shift. If it happens again,
>> + * set lenth to ~0ULL.
>> + */
>> + while (shift) {
>> + if (len & (1ULL << 63)) {
>> + if (!is_div) {
>> + len = div64_u64(len, r->mult);
>> + is_div = true;
>> + } else {
>> + /* overflow happens */
>> + len = ~0ULL;
>> + is_div = true;
>> + break;
>> + }
>> + }
>> + len <<= 1;
>> + shift--;
>> + }
>> + if (!is_div)
>> + len = div64_u64(len, r->mult);
>> +
>> + if (unlikely(r->linklayer == TC_LINKLAYER_ATM))
>> + len = (len / 53) * 48;
>> +
>> + if (len > r->overhead)
>> + len -= r->overhead;
>> + else
>> + len = 0;
>> +
>> + return len;
>> +}
>> +
>
> Are we 100% sure, that the conversion is accurate between
> psched_l2t_ns() and psched_ns_t2l for all possible rates.
>
> E.g. why is it that r->shift have to be recalculate (orig created in
> psched_ratecfg_precompute()).
It don't recalculate r->shift, it just do shift bit by bit in case that
len overflows. If len overflows, set it to ~0ULL.
I would like to use the way you suggest to calculate the max_size.
So forget about this function.:)
>
>
>> void psched_ratecfg_precompute(struct psched_ratecfg *r,
>> const struct tc_ratespec *conf,
>> u64 rate64);
>> diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
>> index 68f9859..eb9ce7b 100644
>> --- a/net/sched/sch_tbf.c
>> +++ b/net/sched/sch_tbf.c
>> @@ -279,7 +279,7 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
>> struct qdisc_rate_table *rtab = NULL;
>> struct qdisc_rate_table *ptab = NULL;
>> struct Qdisc *child = NULL;
>> - int max_size, n;
>> + u32 max_size = 0;
>> u64 rate64 = 0, prate64 = 0;
>>
>> err = nla_parse_nested(tb, TCA_TBF_MAX, opt, tbf_policy);
>> @@ -291,33 +291,20 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
>> goto done;
>>
>> qopt = nla_data(tb[TCA_TBF_PARMS]);
>> - rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]);
>> - if (rtab == NULL)
>> - goto done;
>> -
>> - if (qopt->peakrate.rate) {
>> - if (qopt->peakrate.rate > qopt->rate.rate)
>> - ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]);
>> - if (ptab == NULL)
>> - goto done;
>> + if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE) {
>> + rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]);
>> + if (rtab) {
>> + qdisc_put_rtab(rtab);
>> + rtab = NULL;
>> + }
>
> This is correct code construct, for backward compatible reading of the
> rate table.
>
> But, notice how your free this at once, which means you also should
> cleanup the exit/done: section.
Agreed, I will change it in v3.
Thanks!
>
>
>
>> }
>> -
>> - for (n = 0; n < 256; n++)
>> - if (rtab->data[n] > qopt->buffer)
>> - break;
>> - max_size = (n << qopt->rate.cell_log) - 1;
>
> This is here we could do the quick-and-dirty solution:
>
> for (n = 0; n < 65535; n++)
> if (psched_l2t_ns(&qopt->rate, n) > q->buffer)
> break;
> max_size = n;
>
>
>
>> - if (ptab) {
>> - int size;
>> -
>> - for (n = 0; n < 256; n++)
>> - if (ptab->data[n] > qopt->mtu)
>> - break;
>> - size = (n << qopt->peakrate.cell_log) - 1;
>> - if (size < max_size)
>> - max_size = size;
>> + if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE) {
>> + ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]);
>> + if (ptab) {
>> + qdisc_put_rtab(ptab);
>> + ptab = NULL;
>> + }
>> }
>> - if (max_size < 0)
>> - goto done;
>>
>> if (q->qdisc != &noop_qdisc) {
>> err = fifo_set_limit(q->qdisc, qopt->limit);
>> @@ -339,25 +326,45 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
>> }
>> q->limit = qopt->limit;
>> q->mtu = PSCHED_TICKS2NS(qopt->mtu);
>> - q->max_size = max_size;
>> q->buffer = PSCHED_TICKS2NS(qopt->buffer);
>> q->tokens = q->buffer;
>> q->ptokens = q->mtu;
>>
>> if (tb[TCA_TBF_RATE64])
>> rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
>> - psched_ratecfg_precompute(&q->rate, &rtab->rate, rate64);
>> - if (ptab) {
>> + psched_ratecfg_precompute(&q->rate, &qopt->rate, rate64);
>> + if (!q->rate.rate_bytes_ps)
>> + goto unlock_done;
>> + max_size = min_t(u64, psched_ns_t2l(&q->rate, q->buffer), ~0);
>> + max_size = min_t(u32, max_size, (256 << qopt->rate.cell_log) - 1);
>
> The rate system and the rate.cell_log is not really used anymore, so
> its a bit strange to use it. Perhaps it's even a bug to base a
> calculation on this.
cell_log is calculated from mtu(user input in bytes) in userspace.
In the old calculation, max_size should be smaller than (256 << cell_log)
which means it's smaller than mtu.
>
>> +
>> + if (qopt->peakrate.rate) {
>> + u64 size = 0;
>> if (tb[TCA_TBF_PRATE64])
>> prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]);
>> - psched_ratecfg_precompute(&q->peak, &ptab->rate, prate64);
>> + psched_ratecfg_precompute(&q->peak, &qopt->peakrate, prate64);
>> + size = psched_ns_t2l(&q->peak, q->mtu);
>> + max_size = min_t(u64, max_size, size);
>> + max_size = min_t(u32,
>> + max_size,
>> + (256 << qopt->peakrate.cell_log) - 1);
>> q->peak_present = true;
>> } else {
>> q->peak_present = false;
>> }
>>
>> + if (!max_size)
>> + goto unlock_done;
>> + q->max_size = max_size;
>> +
>> sch_tree_unlock(sch);
>> err = 0;
>> +
>> + if (0) {
>
> I really dislike this construct. I'm afraid what a dumb compile would
> optimized this to.
OK, change it in v3.
Thanks!
>
>> +unlock_done:
>> + sch_tree_unlock(sch);
>> + err = -EINVAL;
>> + }
>> done:
>> if (rtab)
>> qdisc_put_rtab(rtab);
>
> This could be cleaned up, as we already have released the rtab's.
>
>
^ permalink raw reply
* Re: MLD maturity in kernel version 2.6.32.60
From: Simon Schneider @ 2013-11-19 6:11 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: Hannes Frederic Sowa, netdev
In-Reply-To: <528AACF4.1090302@redhat.com>
First of all, many thanks for your quick replies.
Unfortunately, we're only part of a big project, so decision about the
kernel version is not really in our hands.
I.e. we're pretty much fixed on 2.6.32.60.
I had a look at the information about Daniel's patches and I also
searched CHANGE LOGs for MLD related stuff.
But I didn't find patches/fixes that seem to address the very basic
issues we have seen.
Would you say that even in 2.6.32.60:
- with force_mld_version=0, MLDv2 with fallback to MLDv1 should
basically work (apart from "details" like wrong timer calculation)
- with force_mld_version=1, we should never see MLDv2 messages being
generated?
best regards, Simon
Am 19.11.2013 01:12, schrieb Daniel Borkmann:
> On 11/18/2013 11:18 PM, Hannes Frederic Sowa wrote:
>> On Mon, Nov 18, 2013 at 01:17:28PM +0100, Simon Schneider wrote:
>>> in a development project, we started evaluating MLD functionality.
>>>
>>> Our development is based on kernel version 2.6.32.60.
>>>
>>> We noticed some pretty basic issues:
>>>
>>> - With force_mld_version set to 0 (we expect "MLDv2 with MLDv1
>>> fallback"), we saw only MLDv2 messages, the fallback to MLDv1 didn't
>>> seem to work, when we sent MLDv1 messages to the unit.
>>> - With force_mld_version set to 1 (we expect "MLDv1 only mode"), we
>>> also saw MLDv2 messages being generated.
>>>
>>> Can someone give a general statement about the MLD implementation
>>> maturity in kernel 2.6.32.60? Are there known bugs that would
>>> explain the above observations?
>>>
>>> We need to see whether it makes sense to put further effort in
>>> investigating/fixing any MLD related issue we see.
>>>
>>> If this is the wrong list to ask this kind of question, please point
>>> me to the correct one.
>>
>> It would be great if you could share test results with newer kernel
>> with us.
>
> Indeed, please do so, thus in case something is still missing so that
> we can fix it.
>
>> Last time I checked we did correctly fallback to MDLv1 mode but it
>> has been a
>> while.
>
> Yes, the fallback timeout should work now.
>
>> If you come up with a specific patch from Daniel's series which fixes
>> the
>> issues you are seeing, we can think about including this to stable.
>>
>> There are still some issues in mld: we are currently a bit too noisy
>> for my
>> taste (e.g. on re-enabling interfaces). This is a big problem for large
>> wireless networks e.g.
>
> There's also still one issue which I am hesitant to implement, as i) I
> don't
> think it's overly useful, ii) nobody complained so far. :-)
>
> In RFC2710 (MLD v1 spec), it says:
>
> 3.7. Other fields
>
> The length of a received MLD message is computed by taking the IPv6
> Payload Length value and subtracting the length of any IPv6 extension
> headers present between the IPv6 header and the MLD message. If that
> length is greater than 24 octets, that indicates that there are other
> fields present beyond the fields described above, perhaps belonging
> to a future backwards-compatible version of MLD. An implementation
> of the version of MLD specified in this document MUST NOT send an MLD
> message longer than 24 octets and MUST ignore anything past the first
> 24 octets of a received MLD message. In all cases, the MLD checksum
> MUST be computed over the entire MLD message, not just the first 24
> octets.
>
> Then, RFC3810 which "updates" RFC2710 obviously has a bigger message
> length
> than that. In igmp6_event_query(), we only check for len ==
> MLD_V1_QUERY_LEN
> and process MLD v1. Now, in case of MLD v1-only fallback, we MUST only
> operate in v1 mode.
>
> Now, in case a v2 message comes in we could assume above statement "if
> that length is greater than 24 octets, that indicates that there are
> other
> fields present beyond the fields described above, perhaps belonging to a
> future backwards-compatible version of MLD".
>
> But then on the other hand, we get completely wrong "Maximum Response
> Delay"
> codes in the packet header as they are differently encoded in MLD v1
> and MLD
> v2 thus not really backwards compatible.
^ permalink raw reply
* Re: 3.12.0+ INFO: inconsistent lock state
From: Cong Wang @ 2013-11-19 6:30 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
In-Reply-To: <23618767.907181384423756972.JavaMail.weblogic@epv6ml03>
On Thu, 14 Nov 2013 at 10:09 GMT, Jongman Heo <jongman.heo@samsung.com> wrote:
>
> Hi,
>
> With current linus git (HEAD 4fbf888accb3), I got following kernel message.
> Maybe related to commit 827da44c6141 ("net: Explicitly initialize u64_stats_sync structures for lockdep") ?
>
> [ 43.886589] =================================
> [ 43.886590] [ INFO: inconsistent lock state ]
> [ 43.886593] 3.12.0+ #34 Not tainted
> [ 43.886594] ---------------------------------
> [ 43.886595] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
> [ 43.886597] swapper/0/0 [HC0[0]:SC1[1]:HE1:SE0] takes:
> [ 43.886599] (&af_inet_stats->syncp.seq){+.?...}, at: [<c09dd983>] __netif_receive_skb_core+0x513/0x6a0
> [ 43.886609] {SOFTIRQ-ON-W} state was registered at:
> [ 43.886610] [<c04a08b7>] __lock_acquire+0x467/0x1830
> [ 43.886614] [<c04a1d18>] lock_acquire+0x98/0x120
> [ 43.886617] [<c0a3718a>] ip4_datagram_connect+0x2ea/0x310
> [ 43.886621] [<c0a44cfa>] inet_dgram_connect+0x2a/0x80
> [ 43.886624] [<c09c8481>] SYSC_connect+0xb1/0xd0
> [ 43.886627] [<c09c9366>] SYSC_socketcall+0x226/0x980
> [ 43.886629] [<c09c9b93>] SyS_socketcall+0x13/0x20
> [ 43.886631] [<c0b03bcd>] sysenter_do_call+0x12/0x38
This is fixed by:
http://marc.info/?l=linux-netdev&m=138446510213411&w=2
^ permalink raw reply
* Re: [BUG,REGRESSION?] 3.11.6+,3.12: GbE iface rate drops to few KB/s
From: Arnaud Ebalard @ 2013-11-19 6:44 UTC (permalink / raw)
To: Eric Dumazet
Cc: Thomas Petazzoni, Florian Fainelli, simon.guinot, netdev,
edumazet, Cong Wang, Willy Tarreau, linux-arm-kernel
In-Reply-To: <1384710098.8604.58.camel@edumazet-glaptop2.roam.corp.google.com>
Hi,
Eric Dumazet <eric.dumazet@gmail.com> writes:
> On Sun, 2013-11-17 at 15:19 +0100, Willy Tarreau wrote:
>
>>
>> So it is fairly possible that in your case you can't fill the link if you
>> consume too many descriptors. For example, if your server uses TCP_NODELAY
>> and sends incomplete segments (which is quite common), it's very easy to
>> run out of descriptors before the link is full.
>
> BTW I have a very simple patch for TCP stack that could help this exact
> situation...
>
> Idea is to use TCP Small Queue so that we dont fill qdisc/TX ring with
> very small frames, and let tcp_sendmsg() have more chance to fill
> complete packets.
>
> Again, for this to work very well, you need that NIC performs TX
> completion in reasonable amount of time...
>
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index 3dc0c6c..10456cf 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c
> @@ -624,13 +624,19 @@ static inline void tcp_push(struct sock *sk, int flags, int mss_now,
> {
> if (tcp_send_head(sk)) {
> struct tcp_sock *tp = tcp_sk(sk);
> + struct sk_buff *skb = tcp_write_queue_tail(sk);
>
> if (!(flags & MSG_MORE) || forced_push(tp))
> - tcp_mark_push(tp, tcp_write_queue_tail(sk));
> + tcp_mark_push(tp, skb);
>
> tcp_mark_urg(tp, flags);
> - __tcp_push_pending_frames(sk, mss_now,
> - (flags & MSG_MORE) ? TCP_NAGLE_CORK : nonagle);
> + if (flags & MSG_MORE)
> + nonagle = TCP_NAGLE_CORK;
> + if (atomic_read(&sk->sk_wmem_alloc) > 2048) {
> + set_bit(TSQ_THROTTLED, &tp->tsq_flags);
> + nonagle = TCP_NAGLE_CORK;
> + }
> + __tcp_push_pending_frames(sk, mss_now, nonagle);
> }
> }
I did some test regarding mvneta perf on current linus tree (commit
2d3c627502f2a9b0, w/ c9eeec26e32e "tcp: TSQ can use a dynamic limit"
reverted). It has Simon's tclk patch for mvebu (1022c75f5abd, "clk:
armada-370: fix tclk frequencies"). Kernel has some debug options
enabled and the patch above is not applied. I will spend some time on
this two directions this evening. The idea was to get some numbers on
the impact of TCP send window size and tcp_limit_output_bytes for
mvneta.
The test is done with a laptop (Debian, 3.11.0, e1000e) directly
connected to a RN102 (Marvell Armada 370 @1.2GHz, mvneta). The RN102
is running Debian armhf with an Apache2 serving a 1GB file from ext4
over lvm over RAID1 from 2 WD30EFRX. The client is nothing fancy, i.e.
a simple wget w/ -O /dev/null option.
With the exact same setup on a ReadyNAS Duo v2 (Kirkwood 88f6282
@1.6GHz, mv643xx_eth), I managed to get a throughput of 108MB/s
(cannot remember the kernel version but sth between 3.8 and 3.10.
So with that setup:
w/ TCP send window set to 4MB: 17.4 MB/s
w/ TCP send window set to 2MB: 16.2 MB/s
w/ TCP send window set to 1MB: 15.6 MB/s
w/ TCP send window set to 512KB: 25.6 MB/s
w/ TCP send window set to 256KB: 57.7 MB/s
w/ TCP send window set to 128KB: 54.0 MB/s
w/ TCP send window set to 64KB: 46.2 MB/s
w/ TCP send window set to 32KB: 42.8 MB/s
Then, I started playing w/ tcp_limit_output_bytes (default is 131072),
w/ TCP send window set to 256KB:
tcp_limit_output_bytes set to 512KB: 59.3 MB/s
tcp_limit_output_bytes set to 256KB: 58.5 MB/s
tcp_limit_output_bytes set to 128KB: 56.2 MB/s
tcp_limit_output_bytes set to 64KB: 32.1 MB/s
tcp_limit_output_bytes set to 32KB: 4.76 MB/s
As a side note, during the test, I sometimes gets peak for some seconds
at the beginning at 90MB/s which tend to confirm what WIlly wrote,
i.e. that the hardware can do more.
Cheers,
a+
^ permalink raw reply
* [PATCH net v3 1/2] net: sched: tbf: fix calculation of max_size
From: Yang Yingliang @ 2013-11-19 7:25 UTC (permalink / raw)
To: davem, netdev; +Cc: eric.dumazet, brouer, jpirko, jbrouer
In-Reply-To: <1384845939-8424-1-git-send-email-yangyingliang@huawei.com>
commit b757c9336d63f94c6b57532(tbf: improved accuracy at high rates)
introduce a regression.
With the follow command:
tc qdisc add dev eth1 root handle 1: tbf latency 50ms burst 10KB rate 30gbit mtu 64k
Without this patch, the max_size value is 10751(bytes).
But, in fact, the real max_size value should be smaller than 7440(bytes).
Or a packet whose length is bigger than 7440 will cause network congestion.
Because the packet is so big that can't get enough tokens. Even all the tokens
in the buffer is given to the packet.
With this patch, the max_size value is 7440(bytes).
The packets whose length is bigger than 7440(bytes) will be dropped or reshape
in tbf_enqueue().
Suggested-by: Jesper Dangaard Brouer <jbrouer@redhat.com>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
net/sched/sch_tbf.c | 71 ++++++++++++++++++++++++++++-------------------------
1 file changed, 37 insertions(+), 34 deletions(-)
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 68f9859..c194129 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -291,33 +291,20 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
goto done;
qopt = nla_data(tb[TCA_TBF_PARMS]);
- rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]);
- if (rtab == NULL)
- goto done;
-
- if (qopt->peakrate.rate) {
- if (qopt->peakrate.rate > qopt->rate.rate)
- ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]);
- if (ptab == NULL)
- goto done;
+ if (qopt->rate.linklayer == TC_LINKLAYER_UNAWARE) {
+ rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]);
+ if (rtab) {
+ qdisc_put_rtab(rtab);
+ rtab = NULL;
+ }
}
-
- for (n = 0; n < 256; n++)
- if (rtab->data[n] > qopt->buffer)
- break;
- max_size = (n << qopt->rate.cell_log) - 1;
- if (ptab) {
- int size;
-
- for (n = 0; n < 256; n++)
- if (ptab->data[n] > qopt->mtu)
- break;
- size = (n << qopt->peakrate.cell_log) - 1;
- if (size < max_size)
- max_size = size;
+ if (qopt->peakrate.linklayer == TC_LINKLAYER_UNAWARE) {
+ ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]);
+ if (ptab) {
+ qdisc_put_rtab(ptab);
+ ptab = NULL;
+ }
}
- if (max_size < 0)
- goto done;
if (q->qdisc != &noop_qdisc) {
err = fifo_set_limit(q->qdisc, qopt->limit);
@@ -339,30 +326,46 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
}
q->limit = qopt->limit;
q->mtu = PSCHED_TICKS2NS(qopt->mtu);
- q->max_size = max_size;
q->buffer = PSCHED_TICKS2NS(qopt->buffer);
q->tokens = q->buffer;
q->ptokens = q->mtu;
if (tb[TCA_TBF_RATE64])
rate64 = nla_get_u64(tb[TCA_TBF_RATE64]);
- psched_ratecfg_precompute(&q->rate, &rtab->rate, rate64);
- if (ptab) {
+ psched_ratecfg_precompute(&q->rate, &qopt->rate, rate64);
+ if (!q->rate.rate_bytes_ps)
+ goto unlock_done;
+ for (n = 0; n < 65536; n++)
+ if (psched_l2t_ns(&q->rate, n) > q->buffer)
+ break;
+ max_size = min_t(u32, n, (256ULL << qopt->rate.cell_log) - 1);
+
+ if (qopt->peakrate.rate) {
+ int size = 0;
if (tb[TCA_TBF_PRATE64])
prate64 = nla_get_u64(tb[TCA_TBF_PRATE64]);
- psched_ratecfg_precompute(&q->peak, &ptab->rate, prate64);
+ psched_ratecfg_precompute(&q->peak, &qopt->peakrate, prate64);
+ for (n = 0; n < 65536; n++)
+ if (psched_l2t_ns(&q->peak, n) > q->mtu)
+ break;
+ size = min_t(u32, n, (256ULL << qopt->rate.cell_log) - 1);
+ max_size = min_t(u32, max_size, size);
q->peak_present = true;
} else {
q->peak_present = false;
}
+ if (!max_size)
+ goto unlock_done;
+ q->max_size = max_size;
+
sch_tree_unlock(sch);
- err = 0;
+ return 0;
+
+unlock_done:
+ sch_tree_unlock(sch);
+ err = -EINVAL;
done:
- if (rtab)
- qdisc_put_rtab(rtab);
- if (ptab)
- qdisc_put_rtab(ptab);
return err;
}
--
1.8.0
^ permalink raw reply related
* [PATCH net v3 2/2] net: sched: htb: fix calculation of quantum
From: Yang Yingliang @ 2013-11-19 7:25 UTC (permalink / raw)
To: davem, netdev; +Cc: eric.dumazet, brouer, jpirko, jbrouer
In-Reply-To: <1384845939-8424-1-git-send-email-yangyingliang@huawei.com>
Now, 32bit rates may be not the true rate.
So use rate_bytes_ps which is from
max(rate32, rate64) to calcualte quantum.
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Acked-by: Eric Dumazet <edumazet@google.com>
---
net/sched/sch_htb.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 0e1e38b..57c6678 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1477,11 +1477,20 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
sch_tree_lock(sch);
}
+ rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0;
+
+ ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0;
+
+ psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64);
+ psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64);
+
/* it used to be a nasty bug here, we have to check that node
* is really leaf before changing cl->un.leaf !
*/
if (!cl->level) {
- cl->quantum = hopt->rate.rate / q->rate2quantum;
+ u64 quantum = div64_u64(cl->rate.rate_bytes_ps,
+ q->rate2quantum);
+ cl->quantum = min_t(u64, quantum, INT_MAX);
if (!hopt->quantum && cl->quantum < 1000) {
pr_warning(
"HTB: quantum of class %X is small. Consider r2q change.\n",
@@ -1500,13 +1509,6 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
cl->prio = TC_HTB_NUMPRIO - 1;
}
- rate64 = tb[TCA_HTB_RATE64] ? nla_get_u64(tb[TCA_HTB_RATE64]) : 0;
-
- ceil64 = tb[TCA_HTB_CEIL64] ? nla_get_u64(tb[TCA_HTB_CEIL64]) : 0;
-
- psched_ratecfg_precompute(&cl->rate, &hopt->rate, rate64);
- psched_ratecfg_precompute(&cl->ceil, &hopt->ceil, ceil64);
-
cl->buffer = PSCHED_TICKS2NS(hopt->buffer);
cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer);
--
1.8.0
^ permalink raw reply related
* [PATCH net v3 0/2] net: sched: fix some issues
From: Yang Yingliang @ 2013-11-19 7:25 UTC (permalink / raw)
To: davem, netdev; +Cc: eric.dumazet, brouer, jpirko, jbrouer
fix a regression introduced by commit b757c9336d63f94c6b57532
(tbf: improved accuracy at high rates).
fix quantum calculation introduced by 64bit rates.
v2
patch 1/2: redescribe the regression.
patch 2/2: add Eric's ack.
v3
patch 1/2: use psched_l2t_ns to calculate max_size
and cleanup exit/done section suggested by Jesper.
Yang Yingliang (2):
net: sched: tbf: fix calculation of max_size
net: sched: htb: fix calculation of quantum
net/sched/sch_htb.c | 18 ++++++++------
net/sched/sch_tbf.c | 71 ++++++++++++++++++++++++++++-------------------------
2 files changed, 47 insertions(+), 42 deletions(-)
--
1.8.0
^ permalink raw reply
* Re: MLD maturity in kernel version 2.6.32.60
From: Daniel Borkmann @ 2013-11-19 7:29 UTC (permalink / raw)
To: simon-schneider; +Cc: Hannes Frederic Sowa, netdev
In-Reply-To: <528B0105.1080101@gmx.net>
On 11/19/2013 07:11 AM, Simon Schneider wrote:
> First of all, many thanks for your quick replies.
>
> Unfortunately, we're only part of a big project, so decision about the kernel version is not really in our hands.
>
> I.e. we're pretty much fixed on 2.6.32.60.
>
> I had a look at the information about Daniel's patches and I also searched CHANGE LOGs for MLD related stuff.
> But I didn't find patches/fixes that seem to address the very basic issues we have seen.
So what's missing in 3.13? Can you elaborate on "very basic issues"?
> Would you say that even in 2.6.32.60:
> - with force_mld_version=0, MLDv2 with fallback to MLDv1 should basically work (apart from "details" like wrong timer calculation)
> - with force_mld_version=1, we should never see MLDv2 messages being generated?
From the code in 3.10 and earlier (therefore also 2.6.32.60), it seems that even if
we'd be in v1 fallback, nothing prevents us to process a v2 message as we would do
normally at least in igmp6_event_query(), which is not correct as we apply knowledge
how to process a v2 message although we're in v1-only fallback mode.
We have the macro MLD_V1_SEEN(idev) in these versions, which results always to true,
but we shouldn't even process it further at this point in igmp6_event_query(). So,
again, I'd recommend to backport the patchset and its dependencies to your kernel,
or just try out the latest one first.
> best regards, Simon
>
>
> Am 19.11.2013 01:12, schrieb Daniel Borkmann:
>> On 11/18/2013 11:18 PM, Hannes Frederic Sowa wrote:
>>> On Mon, Nov 18, 2013 at 01:17:28PM +0100, Simon Schneider wrote:
>>>> in a development project, we started evaluating MLD functionality.
>>>>
>>>> Our development is based on kernel version 2.6.32.60.
>>>>
>>>> We noticed some pretty basic issues:
>>>>
>>>> - With force_mld_version set to 0 (we expect "MLDv2 with MLDv1 fallback"), we saw only MLDv2 messages, the fallback to MLDv1 didn't seem to work, when we sent MLDv1 messages to the unit.
>>>> - With force_mld_version set to 1 (we expect "MLDv1 only mode"), we also saw MLDv2 messages being generated.
>>>>
>>>> Can someone give a general statement about the MLD implementation maturity in kernel 2.6.32.60? Are there known bugs that would explain the above observations?
>>>>
>>>> We need to see whether it makes sense to put further effort in investigating/fixing any MLD related issue we see.
>>>>
>>>> If this is the wrong list to ask this kind of question, please point me to the correct one.
>>>
>>> It would be great if you could share test results with newer kernel with us.
>>
>> Indeed, please do so, thus in case something is still missing so that we can fix it.
>>
>>> Last time I checked we did correctly fallback to MDLv1 mode but it has been a
>>> while.
>>
>> Yes, the fallback timeout should work now.
>>
>>> If you come up with a specific patch from Daniel's series which fixes the
>>> issues you are seeing, we can think about including this to stable.
>>>
>>> There are still some issues in mld: we are currently a bit too noisy for my
>>> taste (e.g. on re-enabling interfaces). This is a big problem for large
>>> wireless networks e.g.
>>
>> There's also still one issue which I am hesitant to implement, as i) I don't
>> think it's overly useful, ii) nobody complained so far. :-)
>>
>> In RFC2710 (MLD v1 spec), it says:
>>
>> 3.7. Other fields
>>
>> The length of a received MLD message is computed by taking the IPv6
>> Payload Length value and subtracting the length of any IPv6 extension
>> headers present between the IPv6 header and the MLD message. If that
>> length is greater than 24 octets, that indicates that there are other
>> fields present beyond the fields described above, perhaps belonging
>> to a future backwards-compatible version of MLD. An implementation
>> of the version of MLD specified in this document MUST NOT send an MLD
>> message longer than 24 octets and MUST ignore anything past the first
>> 24 octets of a received MLD message. In all cases, the MLD checksum
>> MUST be computed over the entire MLD message, not just the first 24
>> octets.
>>
>> Then, RFC3810 which "updates" RFC2710 obviously has a bigger message length
>> than that. In igmp6_event_query(), we only check for len == MLD_V1_QUERY_LEN
>> and process MLD v1. Now, in case of MLD v1-only fallback, we MUST only
>> operate in v1 mode.
>>
>> Now, in case a v2 message comes in we could assume above statement "if
>> that length is greater than 24 octets, that indicates that there are other
>> fields present beyond the fields described above, perhaps belonging to a
>> future backwards-compatible version of MLD".
>>
>> But then on the other hand, we get completely wrong "Maximum Response Delay"
>> codes in the packet header as they are differently encoded in MLD v1 and MLD
>> v2 thus not really backwards compatible.
>
^ permalink raw reply
* [PATCH net] virtio-net: fix page refcnt leaking when fail to allocate frag skb
From: Jason Wang @ 2013-11-19 8:05 UTC (permalink / raw)
To: rusty, mst, virtualization, netdev, linux-kernel
Cc: Michael Dalton, Eric Dumazet
We need to drop the refcnt of page when we fail to allocate an skb for frag
list, otherwise it will be leaked. The bug was introduced by commit
2613af0ed18a11d5c566a81f9a6510b73180660a ("virtio_net: migrate mergeable rx
buffers to page frag allocators").
Cc: Michael Dalton <mwdalton@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Cc: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
The patch was needed for 3.12 stable.
---
drivers/net/virtio_net.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 69ad42b..3798517 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -322,9 +322,11 @@ static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb)
head_skb->dev->name);
len = MERGE_BUFFER_LEN;
}
+ page = virt_to_head_page(buf);
if (unlikely(num_skb_frags == MAX_SKB_FRAGS)) {
struct sk_buff *nskb = alloc_skb(0, GFP_ATOMIC);
if (unlikely(!nskb)) {
+ put_page(page);
head_skb->dev->stats.rx_dropped++;
return -ENOMEM;
}
@@ -341,7 +343,6 @@ static int receive_mergeable(struct receive_queue *rq, struct sk_buff *head_skb)
head_skb->len += len;
head_skb->truesize += MERGE_BUFFER_LEN;
}
- page = virt_to_head_page(buf);
offset = buf - (char *)page_address(page);
if (skb_can_coalesce(curr_skb, num_skb_frags, page, offset)) {
put_page(page);
--
1.8.3.2
^ permalink raw reply related
* [PATCH net] xfrm: Release dst if this dst is improper for vti tunnel
From: Fan Du @ 2013-11-19 8:53 UTC (permalink / raw)
To: steffen.klassert, saurabh.mohan; +Cc: davem, netdev
After searching rt by the vti tunnel dst/src parameter,
if this rt has neither attached to any transformation
nor the transformation is not tunnel oriented, this rt
should be released back to ip layer.
otherwise causing dst memory leakage.
Signed-off-by: Fan Du <fan.du@windriver.com>
---
net/ipv4/ip_vti.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 5d9c845..52b802a 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -126,6 +126,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (!rt->dst.xfrm ||
rt->dst.xfrm->props.mode != XFRM_MODE_TUNNEL) {
dev->stats.tx_carrier_errors++;
+ ip_rt_put(rt);
goto tx_error_icmp;
}
tdev = rt->dst.dev;
--
1.7.9.5
^ 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