* Re: [PATCH net-next V5 3/3] tun: rx batching
From: Michael S. Tsirkin @ 2017-01-18 17:03 UTC (permalink / raw)
To: Jason Wang; +Cc: kvm, netdev, virtualization, wexu, stefanha
In-Reply-To: <1484722923-7698-4-git-send-email-jasowang@redhat.com>
On Wed, Jan 18, 2017 at 03:02:03PM +0800, Jason Wang wrote:
> We can only process 1 packet at one time during sendmsg(). This often
> lead bad cache utilization under heavy load. So this patch tries to do
> some batching during rx before submitting them to host network
> stack. This is done through accepting MSG_MORE as a hint from
> sendmsg() caller, if it was set, batch the packet temporarily in a
> linked list and submit them all once MSG_MORE were cleared.
>
> Tests were done by pktgen (burst=128) in guest over mlx4(noqueue) on host:
>
> Mpps -+%
> rx-frames = 0 0.91 +0%
> rx-frames = 4 1.00 +9.8%
> rx-frames = 8 1.00 +9.8%
> rx-frames = 16 1.01 +10.9%
> rx-frames = 32 1.07 +17.5%
> rx-frames = 48 1.07 +17.5%
> rx-frames = 64 1.08 +18.6%
> rx-frames = 64 (no MSG_MORE) 0.91 +0%
>
> User were allowed to change per device batched packets through
> ethtool -C rx-frames. NAPI_POLL_WEIGHT were used as upper limitation
> to prevent bh from being disabled too long.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> drivers/net/tun.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 70 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 8c1d3bd..13890ac 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -218,6 +218,7 @@ struct tun_struct {
> struct list_head disabled;
> void *security;
> u32 flow_count;
> + u32 rx_batched;
> struct tun_pcpu_stats __percpu *pcpu_stats;
> };
>
> @@ -522,6 +523,7 @@ static void tun_queue_purge(struct tun_file *tfile)
> while ((skb = skb_array_consume(&tfile->tx_array)) != NULL)
> kfree_skb(skb);
>
> + skb_queue_purge(&tfile->sk.sk_write_queue);
> skb_queue_purge(&tfile->sk.sk_error_queue);
> }
>
> @@ -1139,10 +1141,46 @@ static struct sk_buff *tun_alloc_skb(struct tun_file *tfile,
> return skb;
> }
>
> +static void tun_rx_batched(struct tun_struct *tun, struct tun_file *tfile,
> + struct sk_buff *skb, int more)
> +{
> + struct sk_buff_head *queue = &tfile->sk.sk_write_queue;
> + struct sk_buff_head process_queue;
> + u32 rx_batched = tun->rx_batched;
> + bool rcv = false;
> +
> + if (!rx_batched || (!more && skb_queue_empty(queue))) {
> + local_bh_disable();
> + netif_receive_skb(skb);
> + local_bh_enable();
> + return;
> + }
> +
> + spin_lock(&queue->lock);
> + if (!more || skb_queue_len(queue) == rx_batched) {
> + __skb_queue_head_init(&process_queue);
> + skb_queue_splice_tail_init(queue, &process_queue);
> + rcv = true;
> + } else {
> + __skb_queue_tail(queue, skb);
> + }
> + spin_unlock(&queue->lock);
> +
> + if (rcv) {
> + struct sk_buff *nskb;
> +
> + local_bh_disable();
> + while ((nskb = __skb_dequeue(&process_queue)))
> + netif_receive_skb(nskb);
> + netif_receive_skb(skb);
> + local_bh_enable();
> + }
> +}
> +
> /* Get packet from user space buffer */
> static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
> void *msg_control, struct iov_iter *from,
> - int noblock)
> + int noblock, bool more)
> {
> struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
> struct sk_buff *skb;
> @@ -1283,9 +1321,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
>
> rxhash = skb_get_hash(skb);
> #ifndef CONFIG_4KSTACKS
> - local_bh_disable();
> - netif_receive_skb(skb);
> - local_bh_enable();
> + tun_rx_batched(tun, tfile, skb, more);
> #else
> netif_rx_ni(skb);
> #endif
> @@ -1311,7 +1347,8 @@ static ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from)
> if (!tun)
> return -EBADFD;
>
> - result = tun_get_user(tun, tfile, NULL, from, file->f_flags & O_NONBLOCK);
> + result = tun_get_user(tun, tfile, NULL, from,
> + file->f_flags & O_NONBLOCK, false);
>
> tun_put(tun);
> return result;
> @@ -1569,7 +1606,8 @@ static int tun_sendmsg(struct socket *sock, struct msghdr *m, size_t total_len)
> return -EBADFD;
>
> ret = tun_get_user(tun, tfile, m->msg_control, &m->msg_iter,
> - m->msg_flags & MSG_DONTWAIT);
> + m->msg_flags & MSG_DONTWAIT,
> + m->msg_flags & MSG_MORE);
> tun_put(tun);
> return ret;
> }
> @@ -1770,6 +1808,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
> tun->align = NET_SKB_PAD;
> tun->filter_attached = false;
> tun->sndbuf = tfile->socket.sk->sk_sndbuf;
> + tun->rx_batched = 0;
>
> tun->pcpu_stats = netdev_alloc_pcpu_stats(struct tun_pcpu_stats);
> if (!tun->pcpu_stats) {
> @@ -2438,6 +2477,29 @@ static void tun_set_msglevel(struct net_device *dev, u32 value)
> #endif
> }
>
> +static int tun_get_coalesce(struct net_device *dev,
> + struct ethtool_coalesce *ec)
> +{
> + struct tun_struct *tun = netdev_priv(dev);
> +
> + ec->rx_max_coalesced_frames = tun->rx_batched;
> +
> + return 0;
> +}
> +
> +static int tun_set_coalesce(struct net_device *dev,
> + struct ethtool_coalesce *ec)
> +{
> + struct tun_struct *tun = netdev_priv(dev);
> +
> + if (ec->rx_max_coalesced_frames > NAPI_POLL_WEIGHT)
> + tun->rx_batched = NAPI_POLL_WEIGHT;
> + else
> + tun->rx_batched = ec->rx_max_coalesced_frames;
> +
> + return 0;
> +}
> +
> static const struct ethtool_ops tun_ethtool_ops = {
> .get_settings = tun_get_settings,
> .get_drvinfo = tun_get_drvinfo,
> @@ -2445,6 +2507,8 @@ static const struct ethtool_ops tun_ethtool_ops = {
> .set_msglevel = tun_set_msglevel,
> .get_link = ethtool_op_get_link,
> .get_ts_info = ethtool_op_get_ts_info,
> + .get_coalesce = tun_get_coalesce,
> + .set_coalesce = tun_set_coalesce,
> };
>
> static int tun_queue_resize(struct tun_struct *tun)
> --
> 2.7.4
^ permalink raw reply
* Re: [PATCH net-next V5 2/3] vhost_net: tx batching
From: Michael S. Tsirkin @ 2017-01-18 17:03 UTC (permalink / raw)
To: Jason Wang; +Cc: virtualization, netdev, kvm, stephen, wexu, stefanha
In-Reply-To: <1484722923-7698-3-git-send-email-jasowang@redhat.com>
On Wed, Jan 18, 2017 at 03:02:02PM +0800, Jason Wang wrote:
> This patch tries to utilize tuntap rx batching by peeking the tx
> virtqueue during transmission, if there's more available buffers in
> the virtqueue, set MSG_MORE flag for a hint for backend (e.g tuntap)
> to batch the packets.
>
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> drivers/vhost/net.c | 23 ++++++++++++++++++++---
> 1 file changed, 20 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 5dc3465..c42e9c3 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -351,6 +351,15 @@ static int vhost_net_tx_get_vq_desc(struct vhost_net *net,
> return r;
> }
>
> +static bool vhost_exceeds_maxpend(struct vhost_net *net)
> +{
> + struct vhost_net_virtqueue *nvq = &net->vqs[VHOST_NET_VQ_TX];
> + struct vhost_virtqueue *vq = &nvq->vq;
> +
> + return (nvq->upend_idx + vq->num - VHOST_MAX_PEND) % UIO_MAXIOV
> + == nvq->done_idx;
> +}
> +
> /* Expects to be always run from workqueue - which acts as
> * read-size critical section for our kind of RCU. */
> static void handle_tx(struct vhost_net *net)
> @@ -394,8 +403,7 @@ static void handle_tx(struct vhost_net *net)
> /* If more outstanding DMAs, queue the work.
> * Handle upend_idx wrap around
> */
> - if (unlikely((nvq->upend_idx + vq->num - VHOST_MAX_PEND)
> - % UIO_MAXIOV == nvq->done_idx))
> + if (unlikely(vhost_exceeds_maxpend(net)))
> break;
>
> head = vhost_net_tx_get_vq_desc(net, vq, vq->iov,
> @@ -454,6 +462,16 @@ static void handle_tx(struct vhost_net *net)
> msg.msg_control = NULL;
> ubufs = NULL;
> }
> +
> + total_len += len;
> + if (total_len < VHOST_NET_WEIGHT &&
> + !vhost_vq_avail_empty(&net->dev, vq) &&
> + likely(!vhost_exceeds_maxpend(net))) {
> + msg.msg_flags |= MSG_MORE;
> + } else {
> + msg.msg_flags &= ~MSG_MORE;
> + }
> +
> /* TODO: Check specific error and bomb out unless ENOBUFS? */
> err = sock->ops->sendmsg(sock, &msg, len);
> if (unlikely(err < 0)) {
> @@ -472,7 +490,6 @@ static void handle_tx(struct vhost_net *net)
> vhost_add_used_and_signal(&net->dev, vq, head, 0);
> else
> vhost_zerocopy_signal_used(net, vq);
> - total_len += len;
> vhost_net_tx_packet(net);
> if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
> vhost_poll_queue(&vq->poll);
> --
> 2.7.4
^ permalink raw reply
* Re: [PATCH] stmicro: add more information to Kconfig
From: David Miller @ 2017-01-18 17:12 UTC (permalink / raw)
To: Joao.Pinto; +Cc: peppe.cavallaro, alexandre.torgue, netdev
In-Reply-To: <8e4b7bbd48a0b2ff1374fdffe6d07dc00659e951.1484664500.git.jpinto@synopsys.com>
From: Joao Pinto <Joao.Pinto@synopsys.com>
Date: Tue, 17 Jan 2017 14:53:07 +0000
> This patch adds more info to stmicro' Kconfig files in order to be clearer
> that the driver can be used by ethernet cards based on 10/100/1000/EQOS
> Synopsys IP Cores.
>
> EQOS was also added stmmac/Kconfig Kconfig, since dwmac4 is in fact EQoS,
> one of Synopsys Ethernet IPs. More info at:
> https://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_qos
>
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
Applied.
^ permalink raw reply
* Re: [PATCH] ip/xfrm: Fix deleteall when having many policies installed
From: Stephen Hemminger @ 2017-01-18 17:03 UTC (permalink / raw)
To: Alexander Heinlein; +Cc: netdev, shemminger
In-Reply-To: <d056322e-7c23-7e19-3bdb-4afa5f04e409@secunet.com>
On Mon, 16 Jan 2017 15:09:01 +0100
Alexander Heinlein <alexander.heinlein@secunet.com> wrote:
> Fix "Policy buffer overflow" error when trying to use deleteall with
> many policies installed.
>
> Signed-off-by: Alexander Heinlein <alexander.heinlein@secunet.com>
> ---
> ip/xfrm_policy.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c
> index cc9c0f1..451b982 100644
> --- a/ip/xfrm_policy.c
> +++ b/ip/xfrm_policy.c
> @@ -732,10 +732,8 @@ static int xfrm_policy_keep(const struct
> sockaddr_nl *who,
Patch is not formatted properly because your mailer is line wrapping
^ permalink raw reply
* Re: [PATCH net-next] net: Remove usage of net_device last_rx member
From: Eric Dumazet @ 2017-01-18 17:23 UTC (permalink / raw)
To: Tobias Klauser
Cc: devel, netdev, b.a.t.m.a.n, linux-m68k, intel-wired-lan,
Jay Vosburgh, Veaceslav Falico, Andy Gospodarek, Mirko Lindner
In-Reply-To: <20170118164501.1934-1-tklauser@distanz.ch>
On Wed, 2017-01-18 at 17:45 +0100, Tobias Klauser wrote:
> The network stack no longer uses the last_rx member of struct net_device
> since the bonding driver switched to use its own private last_rx in
> commit 9f242738376d ("bonding: use last_arp_rx in slave_last_rx()").
>
> However, some drivers still (ab)use the field for their own purposes and
> some driver just update it without actually using it.
>
> Previously, there was an accompanying comment for the last_rx member
> added in commit 4dc89133f49b ("net: add a comment on netdev->last_rx")
> which asked drivers not to update is, unless really needed. However,
> this commend was removed in commit f8ff080dacec ("bonding: remove
> useless updating of slave->dev->last_rx"), so some drivers added later
> on still did update last_rx.
>
> Remove all usage of last_rx and switch three drivers (sky2, atp and
> smc91c92_cs) which actually read and write it to use their own private
> copy in netdev_priv.
>
> Compile-tested with allyesconfig and allmodconfig on x86 and arm.
SGTM, thanks a lot for doing this Tobias.
Acked-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply
* Re: [RFC v2 00/10] HFI Virtual Network Interface Controller (VNIC)
From: Jason Gunthorpe @ 2017-01-18 16:46 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Vishwanathapura, Niranjana, ira.weiny, Doug Ledford, Jeff Kirsher,
David S. Miller, linux-rdma, netdev, dennis.dalessandro
In-Reply-To: <20170118054354.GT32481@mtr-leonro.local>
On Wed, Jan 18, 2017 at 07:43:54AM +0200, Leon Romanovsky wrote:
> > I have started working on porting hfi_vnic as per this new interface.
> > I will post RFC v3 later.
> > Posting the interface definition early for comments.
>
> I wonder how many people will comment it without seeing usage example.
It is my hope that Mellanox will contribute to this and use it for
ipoib - we've have had conversations along these lines in the
past... Apparently mlx4/5 could run quite a bit faster if used like
this.
Jason
^ permalink raw reply
* Re: [PATCH v2 net-next] net:add one common config ARCH_WANT_RELAX_ORDER to support relax ordering.
From: Alexander Duyck @ 2017-01-18 17:25 UTC (permalink / raw)
To: David Laight
Cc: David Miller, maowenan@huawei.com, netdev@vger.kernel.org,
jeffrey.t.kirsher@intel.com
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6DB0266CD6@AcuExch.aculab.com>
On Wed, Jan 18, 2017 at 8:22 AM, David Laight <David.Laight@aculab.com> wrote:
> From: David Miller
>> Sent: 17 January 2017 19:16
>> > Relax ordering(RO) is one feature of 82599 NIC, to enable this feature can
>> > enhance the performance for some cpu architecure, such as SPARC and so on.
>> > Currently it only supports one special cpu architecture(SPARC) in 82599
>> > driver to enable RO feature, this is not very common for other cpu architecture
>> > which really needs RO feature.
>> > This patch add one common config CONFIG_ARCH_WANT_RELAX_ORDER to set RO feature,
>> > and should define CONFIG_ARCH_WANT_RELAX_ORDER in sparc Kconfig firstly.
>> >
>> > Signed-off-by: Mao Wenan <maowenan@huawei.com>
>>
>> Since no-one has reviewed this patch, and I do not feel comfortable with applying
>> it without such review, I am tossing this patch.
>>
>> If someone eventually reviews it, repost this patch.
>
> Having re-read parts of the PCIe spec I think I'd like someone to
> explain exactly which transfers are affected by the 'relaxed ordering'
> bit and why any re-ordered transactions aren't a problem.
>
> In particular I believe RO allows the write to update the receive
> descriptor ring to overtake a write of receive packet data.
> That could lead to the network stack processing a receive frame
> before it has actually been written.
>
> David
>
The Relaxed Ordering attribute doesn't get applied across the board.
It ends up being limited to a subset of the transactions if I recall
correctly. In this case it is the Tx descriptor write back, and the
Rx data write back. We don't apply the RO bit to any other
transactions.
In the case of Tx descriptor there is no harm in allowing it to be
reordered because we only really read the DD bit so we don't care
about the ordering of the write back. In the case of the Rx data the
Rx descriptor essentially acts as a flush since it is sent without the
RO bit set. So all the writes before it must be completed before the
Rx descriptor write back.
- Alex
^ permalink raw reply
* Re: resend: tcp: performance issue with fastopen connections (mss > window)
From: Alexey Kodanev @ 2017-01-18 17:32 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, netdev, Vasily Isaenko, Neal Cardwell,
Yuchung Cheng, Eric Dumazet
In-Reply-To: <22b07900-2151-a31f-34aa-7fb47c958423@oracle.com>
Hi Eric,
On 01/13/2017 08:07 PM, Alexey Kodanev wrote:
> Hi Eric,
> On 13.01.2017 18:35, Eric Dumazet wrote:
>
>> I would suggest to clamp MSS to half the initial window, but I guess
>> this is impractical since window in SYN/SYNACK are not scaled.
Looks like max_window not correctly initialized for tfo sockets.
On my test machine it has set to '5592320' in tcp_fastopen_create_child().
This diff fixes the issue, the question: is this the right place to do it?
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 4e777a3..33ed508 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -206,6 +206,8 @@ static struct sock *tcp_fastopen_create_child(struct
sock *sk,
*/
tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
+ tp->max_window = tp->snd_wnd;
+
/* Activate the retrans timer so that SYNACK can be retransmitted.
* The request socket is not added to the ehash
* because it's been added to the accept queue directly.
Thanks,
Alexey
^ permalink raw reply related
* Re: [pull request][for-next] Mellanox mlx5 Reorganize core driver directory layout
From: David Miller @ 2017-01-18 17:32 UTC (permalink / raw)
To: saeedm-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb
Cc: saeedm-VPRAkNaXOzVWk0Htik3J/w, dledford-H+wXaHxf7aLQT0dZR+AlfA,
netdev-u79uwXL29TY76Z2rM5mHXA, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
leon-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <CALzJLG--ZRVk0Zy+6UaGCWbOhki+PZnkmrh9rjojU1ZDm_5Y6w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
From: Saeed Mahameed <saeedm-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org>
Date: Mon, 16 Jan 2017 22:30:29 +0200
>> But please bear with me here, what if we queue this patch up to -stable ?
You've got to be seriously kidding me that your idea is to submit an
incredibly diruptive driver rename to -stable to solve this problem.
That is completely a non-starter.
The whole idea is to _MINIMIZE_ the amount of change happening in
-stable in order to avoid regressions and negative consequence for
everyone using the -stable tree.
I am strongly against a major reorganization of this driver, sorry.
The Synopsys folks want to do the same thing for the stmmac driver,
for even more nefarious reasons, and I'm rejecting all of their
attempts to do that as well.
If you look in that thread, they said they would "help" with the
-stable backports, and in there I explained why that is a completely
empty gesture. There are people doing the backports outside of your
spehere of influence, who need to get their work done "right now" and
aren't going to consult you and be on your schedule for doing those
backports.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next] macb: Common code to enable ptp support for SAMA5Dx platforms.
From: Nicolas Ferre @ 2017-01-18 17:32 UTC (permalink / raw)
To: Andrei Pistirica, netdev, linux-kernel, linux-arm-kernel, davem,
harinikatakamlinux, harini.katakam, richardcochran, rafalo
Cc: punnaia, michals, anirudh, boris.brezillon, alexandre.belloni,
tbultel
In-Reply-To: <1484758673-8694-1-git-send-email-andrei.pistirica@microchip.com>
Le 18/01/2017 à 09:57, Andrei Pistirica a écrit :
> This patch does the following:
> - add GEM-PTP interface
> - registers and bitfields for TSU are named according to SAMA5Dx data sheet
> - PTP support based on platform capability
The $subject will certainly never match reality, sadly "enable ptp
support for SAMA5Dx platforms". So, you'd better change it.
(no "." at the end BTW).
> Signed-off-by: Andrei Pistirica <andrei.pistirica@microchip.com>
> ---
> This is just the common code for GEM-PTP support. Code is based on the comments
> related to the following patch series:
> - [RFC PATCH net-next v1-to-4 1/2] macb: Add 1588 support in Cadence GEM.
> - [RFC PATCH net-next v1-to-4 2/2] macb: Enable 1588 support in SAMA5Dx platforms.
>
> Note: Patch on net-next: January 18.
>
> Rafal/Harini, you can continue the work for GME-GXL.
>
> drivers/net/ethernet/cadence/macb.c | 33 ++++++++++++++++-
> drivers/net/ethernet/cadence/macb.h | 74 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 105 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
> index c0fb80a..575022e 100644
> --- a/drivers/net/ethernet/cadence/macb.c
> +++ b/drivers/net/ethernet/cadence/macb.c
> @@ -2085,6 +2085,9 @@ static int macb_open(struct net_device *dev)
>
> netif_tx_start_all_queues(dev);
>
> + if (bp->ptp_info)
> + bp->ptp_info->ptp_init(dev);
> +
> return 0;
> }
>
> @@ -2106,6 +2109,9 @@ static int macb_close(struct net_device *dev)
>
> macb_free_consistent(bp);
>
> + if (bp->ptp_info)
> + bp->ptp_info->ptp_remove(dev);
> +
> return 0;
> }
>
> @@ -2379,6 +2385,17 @@ static int macb_set_ringparam(struct net_device *netdev,
> return 0;
> }
>
> +static int macb_get_ts_info(struct net_device *netdev,
> + struct ethtool_ts_info *info)
> +{
> + struct macb *bp = netdev_priv(netdev);
> +
> + if (bp->ptp_info)
> + return bp->ptp_info->get_ts_info(netdev, info);
> +
> + return ethtool_op_get_ts_info(netdev, info);
> +}
> +
> static const struct ethtool_ops macb_ethtool_ops = {
> .get_regs_len = macb_get_regs_len,
> .get_regs = macb_get_regs,
> @@ -2396,7 +2413,7 @@ static const struct ethtool_ops gem_ethtool_ops = {
> .get_regs_len = macb_get_regs_len,
> .get_regs = macb_get_regs,
> .get_link = ethtool_op_get_link,
> - .get_ts_info = ethtool_op_get_ts_info,
> + .get_ts_info = macb_get_ts_info,
> .get_ethtool_stats = gem_get_ethtool_stats,
> .get_strings = gem_get_ethtool_strings,
> .get_sset_count = gem_get_sset_count,
> @@ -2409,6 +2426,7 @@ static const struct ethtool_ops gem_ethtool_ops = {
> static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
> {
> struct phy_device *phydev = dev->phydev;
> + struct macb *bp = netdev_priv(dev);
>
> if (!netif_running(dev))
> return -EINVAL;
> @@ -2416,7 +2434,17 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
> if (!phydev)
> return -ENODEV;
>
> - return phy_mii_ioctl(phydev, rq, cmd);
> + if (!bp->ptp_info)
> + return phy_mii_ioctl(phydev, rq, cmd);
> +
> + switch (cmd) {
> + case SIOCSHWTSTAMP:
> + return bp->ptp_info->set_hwtst(dev, rq, cmd);
> + case SIOCGHWTSTAMP:
> + return bp->ptp_info->get_hwtst(dev, rq);
> + default:
> + return phy_mii_ioctl(phydev, rq, cmd);
> + }
> }
>
> static int macb_set_features(struct net_device *netdev,
> @@ -2490,6 +2518,7 @@ static void macb_configure_caps(struct macb *bp,
> dcfg = gem_readl(bp, DCFG2);
> if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
> bp->caps |= MACB_CAPS_FIFO_MODE;
> +
Nitpicking, just because other issue exists: this white line doesn't
belong to the patch.
> }
>
> dev_dbg(&bp->pdev->dev, "Cadence caps 0x%08x\n", bp->caps);
> diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
> index d67adad..15f4a13 100644
> --- a/drivers/net/ethernet/cadence/macb.h
> +++ b/drivers/net/ethernet/cadence/macb.h
> @@ -131,6 +131,20 @@
> #define GEM_RXIPCCNT 0x01a8 /* IP header Checksum Error Counter */
> #define GEM_RXTCPCCNT 0x01ac /* TCP Checksum Error Counter */
> #define GEM_RXUDPCCNT 0x01b0 /* UDP Checksum Error Counter */
> +#define GEM_TISUBN 0x01bc /* 1588 Timer Increment Sub-ns */
> +#define GEM_TSH 0x01c0 /* 1588 Timer Seconds High */
> +#define GEM_TSL 0x01d0 /* 1588 Timer Seconds Low */
> +#define GEM_TN 0x01d4 /* 1588 Timer Nanoseconds */
> +#define GEM_TA 0x01d8 /* 1588 Timer Adjust */
> +#define GEM_TI 0x01dc /* 1588 Timer Increment */
> +#define GEM_EFTSL 0x01e0 /* PTP Event Frame Tx Seconds Low */
> +#define GEM_EFTN 0x01e4 /* PTP Event Frame Tx Nanoseconds */
> +#define GEM_EFRSL 0x01e8 /* PTP Event Frame Rx Seconds Low */
> +#define GEM_EFRN 0x01ec /* PTP Event Frame Rx Nanoseconds */
> +#define GEM_PEFTSL 0x01f0 /* PTP Peer Event Frame Tx Secs Low */
> +#define GEM_PEFTN 0x01f4 /* PTP Peer Event Frame Tx Ns */
> +#define GEM_PEFRSL 0x01f8 /* PTP Peer Event Frame Rx Sec Low */
> +#define GEM_PEFRN 0x01fc /* PTP Peer Event Frame Rx Ns */
> #define GEM_DCFG1 0x0280 /* Design Config 1 */
> #define GEM_DCFG2 0x0284 /* Design Config 2 */
> #define GEM_DCFG3 0x0288 /* Design Config 3 */
> @@ -174,6 +188,7 @@
> #define MACB_NCR_TPF_SIZE 1
> #define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */
> #define MACB_TZQ_SIZE 1
> +#define MACB_SRTSM_OFFSET 15
>
> /* Bitfields in NCFGR */
> #define MACB_SPD_OFFSET 0 /* Speed */
> @@ -319,6 +334,32 @@
> #define MACB_PTZ_SIZE 1
> #define MACB_WOL_OFFSET 14 /* Enable wake-on-lan interrupt */
> #define MACB_WOL_SIZE 1
> +#define MACB_DRQFR_OFFSET 18 /* PTP Delay Request Frame Received */
> +#define MACB_DRQFR_SIZE 1
> +#define MACB_SFR_OFFSET 19 /* PTP Sync Frame Received */
> +#define MACB_SFR_SIZE 1
> +#define MACB_DRQFT_OFFSET 20 /* PTP Delay Request Frame Transmitted */
> +#define MACB_DRQFT_SIZE 1
> +#define MACB_SFT_OFFSET 21 /* PTP Sync Frame Transmitted */
> +#define MACB_SFT_SIZE 1
> +#define MACB_PDRQFR_OFFSET 22 /* PDelay Request Frame Received */
> +#define MACB_PDRQFR_SIZE 1
> +#define MACB_PDRSFR_OFFSET 23 /* PDelay Response Frame Received */
> +#define MACB_PDRSFR_SIZE 1
> +#define MACB_PDRQFT_OFFSET 24 /* PDelay Request Frame Transmitted */
> +#define MACB_PDRQFT_SIZE 1
> +#define MACB_PDRSFT_OFFSET 25 /* PDelay Response Frame Transmitted */
> +#define MACB_PDRSFT_SIZE 1
> +#define MACB_SRI_OFFSET 26 /* TSU Seconds Register Increment */
> +#define MACB_SRI_SIZE 1
> +
> +/* Timer increment fields */
> +#define MACB_TI_CNS_OFFSET 0
> +#define MACB_TI_CNS_SIZE 8
> +#define MACB_TI_ACNS_OFFSET 8
> +#define MACB_TI_ACNS_SIZE 8
> +#define MACB_TI_NIT_OFFSET 16
> +#define MACB_TI_NIT_SIZE 8
>
> /* Bitfields in MAN */
> #define MACB_DATA_OFFSET 0 /* data */
> @@ -386,6 +427,17 @@
> #define GEM_PBUF_LSO_OFFSET 27
> #define GEM_PBUF_LSO_SIZE 1
>
> +/* Bitfields in TISUBN */
> +#define GEM_SUBNSINCR_OFFSET 0
> +#define GEM_SUBNSINCR_SIZE 16
> +
> +/* Bitfields in TI */
> +#define GEM_NSINCR_OFFSET 0
> +#define GEM_NSINCR_SIZE 8
> +
> +/* Bitfields in ADJ */
> +#define GEM_ADDSUB_OFFSET 31
> +#define GEM_ADDSUB_SIZE 1
> /* Constants for CLK */
> #define MACB_CLK_DIV8 0
> #define MACB_CLK_DIV16 1
> @@ -417,6 +469,7 @@
> #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000
> #define MACB_CAPS_SG_DISABLED 0x40000000
> #define MACB_CAPS_MACB_IS_GEM 0x80000000
> +#define MACB_CAPS_GEM_HAS_PTP 0x00000020
No, this mask already exists a couple of lines above:
#define MACB_CAPS_JUMBO 0x00000020
That leads to a NACK, sorry (I didn't spotted earlier, BTW).
> /* LSO settings */
> #define MACB_LSO_UFO_ENABLE 0x01
> @@ -782,6 +835,20 @@ struct macb_or_gem_ops {
> int (*mog_rx)(struct macb *bp, int budget);
> };
>
> +/* MACB-PTP interface: adapt to platform needs. */
> +struct macb_ptp_info {
> + void (*ptp_init)(struct net_device *ndev);
> + void (*ptp_remove)(struct net_device *ndev);
> + s32 (*get_ptp_max_adj)(void);
> + unsigned int (*get_tsu_rate)(struct macb *bp);
> + int (*get_ts_info)(struct net_device *dev,
> + struct ethtool_ts_info *info);
> + int (*get_hwtst)(struct net_device *netdev,
> + struct ifreq *ifr);
> + int (*set_hwtst)(struct net_device *netdev,
> + struct ifreq *ifr, int cmd);
> +};
> +
> struct macb_config {
> u32 caps;
> unsigned int dma_burst_length;
> @@ -874,6 +941,8 @@ struct macb {
> unsigned int jumbo_max_len;
>
> u32 wol;
> +
> + struct macb_ptp_info *ptp_info; /* macb-ptp interface */
> };
>
> static inline bool macb_is_gem(struct macb *bp)
> @@ -881,4 +950,9 @@ static inline bool macb_is_gem(struct macb *bp)
> return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
> }
>
> +static inline bool gem_has_ptp(struct macb *bp)
> +{
> + return !!(bp->caps & MACB_CAPS_GEM_HAS_PTP);
> +}
> +
> #endif /* _MACB_H */
Otherwise, I'm okay with the rest.
I suggest to people that will keep the ball rolling on this topic to
take advantage of the chunks of code that Andrei developed with the help
of Richard and the best practices discussed. I think particularly, if it
makes sense with HW, about:
- gem_ptp_do_[rt]xstamp(bp, skb) dereference scheme
- gem_ptp_adjfine() rationale
- gem_get_ptp_peer() if needed
Regards,
--
Nicolas Ferre
^ permalink raw reply
* Re: [RFC] RESEND - rdmatool - tool for RDMA users
From: Leon Romanovsky @ 2017-01-18 17:33 UTC (permalink / raw)
To: Or Gerlitz; +Cc: Ariel Almog, linux-rdma@vger.kernel.org, Linux Netdev List
In-Reply-To: <CAJ3xEMgO496ctgCUp1sW=-pCUyniy7LZb8hSkyNeYsJ1V4aVwg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3155 bytes --]
On Wed, Jan 18, 2017 at 06:48:21PM +0200, Or Gerlitz wrote:
> On Wed, Jan 18, 2017 at 5:19 PM, Ariel Almog
> <arielalmogworkemails@gmail.com> wrote:
> > General
> > *******
> > As of today, there is no single, simple, tool that allows monitoring
> > and configuration of RDMA stack.
>
> Before tool, what kernel UAPI you thought to use?
I'm aware of the following options:
1) netlink
2) RDMA ABI https://www.spinics.net/lists/linux-rdma/msg43960.html
3) ioctl
4) write/read
The items 1 and 2 are preferred options and one of the main goals
for this RFC is to chose between them.
For example, RDMA ABI has native support of querying and discovering
device capabilities via merge tree feature.
https://github.com/matanb10/linux/commit/61aaa4cae1281f6bb32e261f0b8aad489db764ac
>
>
> > rdmatool will provide standard, provider agnostic, user interface.
> > RDMA user can use this interface to
> > * Query RDMA device capabilities
> > * Query RDMA device status and current open resources
> > * Fetching RDMA statistics
> > * Configure RDMA device
> >
> > The rdmatool will have the ability to control RDMA stack which
> > includes the ib_device and RDMA protocol params.
> >
> > It is a good point to highlight the similarity to ethtool. It manages
> > net_device, while rdmatool will manage RDMA stack.
> >
> > As a proposal, it is appealing to have a similar design to ethtool for
> > rdmatool too. As ethtool, it should contain user space part, kernel
> > handler and vendor specific handler(s).
> >
> > Another tool which allows similar functionality is iproute2. Iproute2
> > allows user space tools to configure and query transport, network and
> > link layer. The advantages of using iproute2 is the reuse of existing
> > tool and familiar interface in addition to the wide spreading of this tool.
> >
> > As start point of the discussion, we would like to propose two
> > implementation options for the rdmatool:
> > (1) Build a tool using ABI interface. This will be a RDMA tool
> > which will be distributed as part of RDMA package
> > (2) Enhancing iproute2 to include rdmatool functionality
> >
> > Our opinion is that the new ABI interface provides vast functionality and
> > it will be a waste to use other interface for the same functionality.
> > Each of the proposed implementation above have their advantages, and we
> > would like to hear your opinion regarding this direction.
>
> > I’m posting this RFC in both netdev and linux-rdma communities in
> > order to get feedback on this topic.
>
> What's wrong with the RDMA netlink infrastructure?! it's there for
> years and used
> for various cases by MLNX, did you look on the code?
Nothing wrong, it is one of the valuable options and will be used if
community decides to put this tool under iproute2/ethtool umbrella.
>
> cea05ea IB/core: Add flow control to the portmapper netlink calls
> ae43f82 IB/core: Add IP to GID netlink offload
> 2ca546b IB/sa: Route SA pathrecord query through netlink
> 753f618 RDMA/cma: Add support for netlink statistics export
> b2cbae2 RDMA: Add netlink infrastructure
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: resend: tcp: performance issue with fastopen connections (mss > window)
From: Eric Dumazet @ 2017-01-18 17:35 UTC (permalink / raw)
To: Alexey Kodanev
Cc: Eric Dumazet, David Miller, netdev, Vasily Isaenko, Neal Cardwell,
Yuchung Cheng
In-Reply-To: <3dbbcda8-ce79-641c-cf3b-21f41c563939@oracle.com>
On Wed, Jan 18, 2017 at 9:32 AM, Alexey Kodanev
<alexey.kodanev@oracle.com> wrote:
> Hi Eric,
>
> On 01/13/2017 08:07 PM, Alexey Kodanev wrote:
>
> Looks like max_window not correctly initialized for tfo sockets.
> On my test machine it has set to '5592320' in tcp_fastopen_create_child().
>
> This diff fixes the issue, the question: is this the right place to do it?
>
> diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
> index 4e777a3..33ed508 100644
> --- a/net/ipv4/tcp_fastopen.c
> +++ b/net/ipv4/tcp_fastopen.c
> @@ -206,6 +206,8 @@ static struct sock *tcp_fastopen_create_child(struct
> sock *sk,
> */
> tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
>
> + tp->max_window = tp->snd_wnd;
> +
Excellent catch. Let me test our regression tests with this.
Thanks !
^ permalink raw reply
* Re: [PATCH net-next] net: Remove usage of net_device last_rx member
From: Jay Vosburgh @ 2017-01-18 17:39 UTC (permalink / raw)
To: Tobias Klauser
Cc: devel, Eric Dumazet, netdev, b.a.t.m.a.n, linux-m68k,
intel-wired-lan, Veaceslav Falico, Andy Gospodarek, Mirko Lindner
In-Reply-To: <20170118164501.1934-1-tklauser@distanz.ch>
Tobias Klauser <tklauser@distanz.ch> wrote:
>The network stack no longer uses the last_rx member of struct net_device
>since the bonding driver switched to use its own private last_rx in
>commit 9f242738376d ("bonding: use last_arp_rx in slave_last_rx()").
>
>However, some drivers still (ab)use the field for their own purposes and
>some driver just update it without actually using it.
>
>Previously, there was an accompanying comment for the last_rx member
>added in commit 4dc89133f49b ("net: add a comment on netdev->last_rx")
>which asked drivers not to update is, unless really needed. However,
>this commend was removed in commit f8ff080dacec ("bonding: remove
>useless updating of slave->dev->last_rx"), so some drivers added later
>on still did update last_rx.
>
>Remove all usage of last_rx and switch three drivers (sky2, atp and
>smc91c92_cs) which actually read and write it to use their own private
>copy in netdev_priv.
>
>Compile-tested with allyesconfig and allmodconfig on x86 and arm.
Reviewed-by: Jay Vosburgh <jay.vosburgh@canonical.com>
^ permalink raw reply
* Re: [RFC] RESEND - rdmatool - tool for RDMA users
From: Or Gerlitz @ 2017-01-18 17:50 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Ariel Almog, linux-rdma@vger.kernel.org, Linux Netdev List
In-Reply-To: <20170118173327.GF32481@mtr-leonro.local>
On Wed, Jan 18, 2017 at 7:33 PM, Leon Romanovsky wrote:
> On Wed, Jan 18, 2017 at 06:48:21PM +0200, Or Gerlitz wrote:
>> On Wed, Jan 18, 2017 at 5:19 PM, Ariel Almog
>> <arielalmogworkemails@gmail.com> wrote:
>>> As of today, there is no single, simple, tool that allows monitoring
>>> and configuration of RDMA stack.
>> Before tool, what kernel UAPI you thought to use?
> I'm aware of the following options:
> 1) netlink
> 2) RDMA ABI https://www.spinics.net/lists/linux-rdma/msg43960.html
> 3) ioctl
> 4) write/read
>
> The items 1 and 2 are preferred options and one of the main goals
> for this RFC is to chose between them.
>
> For example, RDMA ABI has native support of querying and discovering
> device capabilities via merge tree feature.
To make it clear, when you wrote ABI in your initial email, I tend to
think it was sort of unclear to the netdev crowd that you are talking
on new UAPI which is now under the works for the IB subsystem, so with
my netdev community member hat, I got confused... anyway
>> > It is a good point to highlight the similarity to ethtool. It manages
>> > net_device, while rdmatool will manage RDMA stack.
ethtool is likely to be ported to use netlink somewhere in the 21st century BTW
>> What's wrong with the RDMA netlink infrastructure?! it's there for
>> years and used
>> for various cases by MLNX, did you look on the code?
> Nothing wrong, it is one of the valuable options and will be used if
> community decides to put this tool under iproute2/ethtool umbrella.
yeah, using netlink sounds good to me, and where you package/maintain
the tool is of 2nd order, 1st decide what UAPI you wonna use. So far
netlink was good for what bunch of use-cases needed.
Or.
>> cea05ea IB/core: Add flow control to the portmapper netlink calls
>> ae43f82 IB/core: Add IP to GID netlink offload
>> 2ca546b IB/sa: Route SA pathrecord query through netlink
>> 753f618 RDMA/cma: Add support for netlink statistics export
>> b2cbae2 RDMA: Add netlink infrastructure
^ permalink raw reply
* [PATCH net-next] bpf: add bpf_probe_read_str helper
From: Gianluca Borello @ 2017-01-18 17:55 UTC (permalink / raw)
To: davem; +Cc: Daniel Borkmann, Alexei Starovoitov, netdev, Gianluca Borello
Provide a simple helper with the same semantics of strncpy_from_unsafe():
int bpf_probe_read_str(void *dst, int size, const void *unsafe_addr)
This gives more flexibility to a bpf program. A typical use case is
intercepting a file name during sys_open(). The current approach is:
SEC("kprobe/sys_open")
void bpf_sys_open(struct pt_regs *ctx)
{
char buf[PATHLEN]; // PATHLEN is defined to 256
bpf_probe_read(buf, sizeof(buf), ctx->di);
/* consume buf */
}
This is suboptimal because the size of the string needs to be estimated
at compile time, causing more memory to be copied than often necessary,
and can become more problematic if further processing on buf is done,
for example by pushing it to userspace via bpf_perf_event_output(),
since the real length of the string is unknown and the entire buffer
must be copied (and defining an unrolled strnlen() inside the bpf
program is a very inefficient and unfeasible approach).
With the new helper, the code can easily operate on the actual string
length rather than the buffer size:
SEC("kprobe/sys_open")
void bpf_sys_open(struct pt_regs *ctx)
{
char buf[PATHLEN]; // PATHLEN is defined to 256
int res = bpf_probe_read_str(buf, sizeof(buf), ctx->di);
/* consume buf, for example push it to userspace via
* bpf_perf_event_output(), but this time we can use
* res (the string length) as event size, after checking
* its boundaries.
*/
}
Another useful use case is when parsing individual process arguments or
individual environment variables navigating current->mm->arg_start and
current->mm->env_start: using this helper and the return value, one can
quickly iterate at the right offset of the memory area.
The code changes simply leverage the already existent
strncpy_from_unsafe() kernel function, which is safe to be called from a
bpf program as it is used in bpf_trace_printk().
Signed-off-by: Gianluca Borello <g.borello@gmail.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
---
include/uapi/linux/bpf.h | 15 ++++++++++++++-
kernel/trace/bpf_trace.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 0eb0e87dbe9f..54a5894bb4ea 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -430,6 +430,18 @@ union bpf_attr {
* @xdp_md: pointer to xdp_md
* @delta: An positive/negative integer to be added to xdp_md.data
* Return: 0 on success or negative on error
+ *
+ * int bpf_probe_read_str(void *dst, int size, const void *unsafe_ptr)
+ * Copy a NUL terminated string from unsafe address. In case the string
+ * length is smaller than size, the target is not padded with further NUL
+ * bytes. In case the string length is larger than size, just count-1
+ * bytes are copied and the last byte is set to NUL.
+ * @dst: destination address
+ * @size: maximum number of bytes to copy, including the trailing NUL
+ * @unsafe_ptr: unsafe address
+ * Return:
+ * > 0 length of the string including the trailing NUL on success
+ * < 0 error
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -476,7 +488,8 @@ union bpf_attr {
FN(set_hash_invalid), \
FN(get_numa_node_id), \
FN(skb_change_head), \
- FN(xdp_adjust_head),
+ FN(xdp_adjust_head), \
+ FN(probe_read_str),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index c22a961d1a42..424daa4586d1 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -395,6 +395,36 @@ static const struct bpf_func_proto bpf_current_task_under_cgroup_proto = {
.arg2_type = ARG_ANYTHING,
};
+BPF_CALL_3(bpf_probe_read_str, void *, dst, u32, size,
+ const void *, unsafe_ptr)
+{
+ int ret;
+
+ /*
+ * The strncpy_from_unsafe() call will likely not fill the entire
+ * buffer, but that's okay in this circumstance as we're probing
+ * arbitrary memory anyway similar to bpf_probe_read() and might
+ * as well probe the stack. Thus, memory is explicitly cleared
+ * only in error case, so that improper users ignoring return
+ * code altogether don't copy garbage; otherwise length of string
+ * is returned that can be used for bpf_perf_event_output() et al.
+ */
+ ret = strncpy_from_unsafe(dst, unsafe_ptr, size);
+ if (unlikely(ret < 0))
+ memset(dst, 0, size);
+
+ return ret;
+}
+
+static const struct bpf_func_proto bpf_probe_read_str_proto = {
+ .func = bpf_probe_read_str,
+ .gpl_only = true,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_PTR_TO_UNINIT_MEM,
+ .arg2_type = ARG_CONST_SIZE,
+ .arg3_type = ARG_ANYTHING,
+};
+
static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id)
{
switch (func_id) {
@@ -432,6 +462,8 @@ static const struct bpf_func_proto *tracing_func_proto(enum bpf_func_id func_id)
return &bpf_current_task_under_cgroup_proto;
case BPF_FUNC_get_prandom_u32:
return &bpf_get_prandom_u32_proto;
+ case BPF_FUNC_probe_read_str:
+ return &bpf_probe_read_str_proto;
default:
return NULL;
}
--
2.11.0
^ permalink raw reply related
* Re: [PATCH 0/6 net-next][V4] Rework inet_csk_get_port
From: David Miller @ 2017-01-18 18:09 UTC (permalink / raw)
To: jbacik; +Cc: hannes, kraigatgoog, eric.dumazet, tom, netdev, kernel-team
In-Reply-To: <20170117155106.22637-1-jbacik@fb.com>
From: Josef Bacik <jbacik@fb.com>
Date: Tue, 17 Jan 2017 07:51:00 -0800
> V3->V4:
> -Removed the random include of addrconf.h that is no longer needed.
>
> V2->V3:
> -Dropped the fastsock from the tb and instead just carry the saddrs, family, and
> ipv6 only flag.
> -Reworked the helper functions to deal with this change so I could still use
> them when checking the fast path.
> -Killed tb->num_owners as per Eric's request.
> -Attached a reproducer to the bottom of this email.
>
> V1->V2:
> -Added a new patch 'inet: collapse ipv4/v6 rcv_saddr_equal functions into one'
> at Hannes' suggestion.
> -Dropped ->bind_conflict and just use the new helper.
> -Fixed a compile bug from the original ->bind_conflict patch.
>
> The original description of the series follows
...
Series applied, thanks!
^ permalink raw reply
* Re: resend: tcp: performance issue with fastopen connections (mss > window)
From: Yuchung Cheng @ 2017-01-18 18:13 UTC (permalink / raw)
To: Eric Dumazet
Cc: Alexey Kodanev, Eric Dumazet, David Miller, netdev,
Vasily Isaenko, Neal Cardwell
In-Reply-To: <CANn89iJn+fC-mMCskczXupj=yhvDijYEn-_NeCphuG8roNCygA@mail.gmail.com>
On Wed, Jan 18, 2017 at 9:35 AM, Eric Dumazet <edumazet@google.com> wrote:
>
> On Wed, Jan 18, 2017 at 9:32 AM, Alexey Kodanev
> <alexey.kodanev@oracle.com> wrote:
> > Hi Eric,
> >
> > On 01/13/2017 08:07 PM, Alexey Kodanev wrote:
> >
>
> > Looks like max_window not correctly initialized for tfo sockets.
> > On my test machine it has set to '5592320' in tcp_fastopen_create_child().
> >
> > This diff fixes the issue, the question: is this the right place to do it?
> >
> > diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
> > index 4e777a3..33ed508 100644
> > --- a/net/ipv4/tcp_fastopen.c
> > +++ b/net/ipv4/tcp_fastopen.c
> > @@ -206,6 +206,8 @@ static struct sock *tcp_fastopen_create_child(struct
> > sock *sk,
> > */
> > tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
> >
> > + tp->max_window = tp->snd_wnd;
> > +
>
> Excellent catch. Let me test our regression tests with this.
Indeed nice catch. Thanks for the investigative work!
>
> Thanks !
^ permalink raw reply
* Re: resend: tcp: performance issue with fastopen connections (mss > window)
From: Eric Dumazet @ 2017-01-18 18:16 UTC (permalink / raw)
To: Yuchung Cheng
Cc: Alexey Kodanev, Eric Dumazet, David Miller, netdev,
Vasily Isaenko, Neal Cardwell
In-Reply-To: <CAK6E8=fL+Gf_uqxALxX8iT7Ew9sxZA_+Ncaa+nh2ZWMkej154w@mail.gmail.com>
On Wed, Jan 18, 2017 at 10:13 AM, Yuchung Cheng <ycheng@google.com> wrote:
> On Wed, Jan 18, 2017 at 9:35 AM, Eric Dumazet <edumazet@google.com> wrote:
>>
>> On Wed, Jan 18, 2017 at 9:32 AM, Alexey Kodanev
>> <alexey.kodanev@oracle.com> wrote:
>> > Hi Eric,
>> >
>> > On 01/13/2017 08:07 PM, Alexey Kodanev wrote:
>> >
>>
>> > Looks like max_window not correctly initialized for tfo sockets.
>> > On my test machine it has set to '5592320' in tcp_fastopen_create_child().
>> >
>> > This diff fixes the issue, the question: is this the right place to do it?
>> >
>> > diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
>> > index 4e777a3..33ed508 100644
>> > --- a/net/ipv4/tcp_fastopen.c
>> > +++ b/net/ipv4/tcp_fastopen.c
>> > @@ -206,6 +206,8 @@ static struct sock *tcp_fastopen_create_child(struct
>> > sock *sk,
>> > */
>> > tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
>> >
>> > + tp->max_window = tp->snd_wnd;
>> > +
>>
>> Excellent catch. Let me test our regression tests with this.
> Indeed nice catch. Thanks for the investigative work!
>
We do have 2 failures, but tests might have depended on undocumented behavior
(For googlers :
Ran 211 tests: 209 passing, 0 flaky 2 failing
Sponge: http://sponge/f1575065-6e1c-4514-bced-9167ce56d2ee
)
Please Alexey submit an official patch, thanks a lot !
^ permalink raw reply
* Re: [PATCH] net: fec: Fixed panic problem with non-tso
From: Pravin Shelar @ 2017-01-18 18:18 UTC (permalink / raw)
To: Eric Dumazet
Cc: Ashizuka, Yuusuke, Andy Duan, netdev@vger.kernel.org,
Pravin B Shelar
In-Reply-To: <1484714132.13165.92.camel@edumazet-glaptop3.roam.corp.google.com>
On Tue, Jan 17, 2017 at 8:35 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Tue, 2017-01-17 at 20:21 -0800, Eric Dumazet wrote:
>> On Wed, 2017-01-18 at 03:12 +0000, Ashizuka, Yuusuke wrote:
>>
>> > indeed.
>> >
>> > In the case of TSO with i.MX6 system (highmem enabled) with 2GB memory,
>> > "this_frag->page.p" did not become highmem area.
>> > (We confirmed by transferring about 100MB of files)
>> >
>> > However, in the case of non-tso on an i.MX6 system with 2GB of memory,
>> > "this_frag->page.p" may become a highmem area.
>> > (Occurred with approximately 2MB of file transfer)
>> >
>> > For non-tso only, I do not know the reason why "this_frag-> page.p"
>> > in this driver shows highmem area.
>>
>> This worries me, since this driver does not set NETIF_F_HIGHDMA in its
>> features.
>>
>> No packet should be given to this driver with a highmem fragment
>>
>> Check is done in illegal_highdma() in net/core/dev.c
>
> This used to work.
>
> I suspect commit ec5f061564238892005257c83565a0b58ec79295
> ("net: Kill link between CSUM and SG features.")
>
> added this bug.
>
> Can you try this hot fix :
>
> diff --git a/net/core/dev.c b/net/core/dev.c
> index ad5959e561166f445bdd9d7260652a338f74cfea..073b832b945257dba9ed47f4bf875605225effc9 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -2773,9 +2773,9 @@ static netdev_features_t harmonize_features(struct sk_buff *skb,
> if (skb->ip_summed != CHECKSUM_NONE &&
> !can_checksum_protocol(features, type)) {
> features &= ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
> - } else if (illegal_highdma(skb->dev, skb)) {
> - features &= ~NETIF_F_SG;
> }
> + if (illegal_highdma(skb->dev, skb))
> + features &= ~NETIF_F_SG;
>
> return features;
> }
Right, this high mem check should be decoupled from csum check.
Thanks,
Pravin.
^ permalink raw reply
* Re: [RFC] RESEND - rdmatool - tool for RDMA users
From: Jason Gunthorpe @ 2017-01-18 18:31 UTC (permalink / raw)
To: Or Gerlitz
Cc: Leon Romanovsky, Ariel Almog, linux-rdma@vger.kernel.org,
Linux Netdev List
In-Reply-To: <CAJ3xEMiR1+NGghUZJ6aGq+=xTdOHU5Ph-BcPii5OUB8dT4Vq-A@mail.gmail.com>
On Wed, Jan 18, 2017 at 07:50:26PM +0200, Or Gerlitz wrote:
> On Wed, Jan 18, 2017 at 7:33 PM, Leon Romanovsky wrote:
> > On Wed, Jan 18, 2017 at 06:48:21PM +0200, Or Gerlitz wrote:
> >> On Wed, Jan 18, 2017 at 5:19 PM, Ariel Almog
> >> <arielalmogworkemails@gmail.com> wrote:
>
> >>> As of today, there is no single, simple, tool that allows monitoring
> >>> and configuration of RDMA stack.
>
> >> Before tool, what kernel UAPI you thought to use?
>
> > I'm aware of the following options:
> > 1) netlink
> > 2) RDMA ABI https://www.spinics.net/lists/linux-rdma/msg43960.html
> > 3) ioctl
> > 4) write/read
> >
> > The items 1 and 2 are preferred options and one of the main goals
> > for this RFC is to chose between them.
> >
> > For example, RDMA ABI has native support of querying and discovering
> > device capabilities via merge tree feature.
>
> To make it clear, when you wrote ABI in your initial email, I tend to
> think it was sort of unclear to the netdev crowd that you are talking
> on new UAPI which is now under the works for the IB subsystem, so with
> my netdev community member hat, I got confused... anyway
I think it depends on what this tool is supposed to cover, but based
on the description, I would start with netlink-only.
The only place verbs covers a similar ground is in 'device
capabilities' - for some of that you might want to open a new-uAPI
verbs fd, but even the capability data from that would not be
totally offensive to be accessed over netlink.
IMHO netlink should cover almost everything found in sysfs today.
I'm also deeply skeptical about driver-specific stuff at this layer,
that sounds like a way to make a big mess.
Jason
^ permalink raw reply
* Re: resend: tcp: performance issue with fastopen connections (mss > window)
From: Yuchung Cheng @ 2017-01-18 18:27 UTC (permalink / raw)
To: Eric Dumazet
Cc: Alexey Kodanev, Eric Dumazet, David Miller, netdev,
Vasily Isaenko, Neal Cardwell
In-Reply-To: <CANn89i+5E0nXEox0EHU7s3me00KegXNA4ZeKQWxQoWRC4jNbHQ@mail.gmail.com>
Googler-only
Hi Eric: yeah I think the test was just due to the TSO chunking
difference between prod and upstream, which I was able to avoid with
this patch re-suited by Neal in b/34128974. In fact, this patch
enables me to run all recovery tests on upstream kernels for my RACK
patch set.
Neal: can we polish and check that in? super useful.
On Wed, Jan 18, 2017 at 10:16 AM, Eric Dumazet <edumazet@google.com> wrote:
> On Wed, Jan 18, 2017 at 10:13 AM, Yuchung Cheng <ycheng@google.com> wrote:
>> On Wed, Jan 18, 2017 at 9:35 AM, Eric Dumazet <edumazet@google.com> wrote:
>>>
>>> On Wed, Jan 18, 2017 at 9:32 AM, Alexey Kodanev
>>> <alexey.kodanev@oracle.com> wrote:
>>> > Hi Eric,
>>> >
>>> > On 01/13/2017 08:07 PM, Alexey Kodanev wrote:
>>> >
>>>
>>> > Looks like max_window not correctly initialized for tfo sockets.
>>> > On my test machine it has set to '5592320' in tcp_fastopen_create_child().
>>> >
>>> > This diff fixes the issue, the question: is this the right place to do it?
>>> >
>>> > diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
>>> > index 4e777a3..33ed508 100644
>>> > --- a/net/ipv4/tcp_fastopen.c
>>> > +++ b/net/ipv4/tcp_fastopen.c
>>> > @@ -206,6 +206,8 @@ static struct sock *tcp_fastopen_create_child(struct
>>> > sock *sk,
>>> > */
>>> > tp->snd_wnd = ntohs(tcp_hdr(skb)->window);
>>> >
>>> > + tp->max_window = tp->snd_wnd;
>>> > +
>>>
>>> Excellent catch. Let me test our regression tests with this.
>> Indeed nice catch. Thanks for the investigative work!
>>
>
> We do have 2 failures, but tests might have depended on undocumented behavior
>
> (For googlers :
> Ran 211 tests: 209 passing, 0 flaky 2 failing
> Sponge: http://sponge/f1575065-6e1c-4514-bced-9167ce56d2ee
> )
>
> Please Alexey submit an official patch, thanks a lot !
^ permalink raw reply
* Re: resend: tcp: performance issue with fastopen connections (mss > window)
From: Neal Cardwell @ 2017-01-18 18:42 UTC (permalink / raw)
To: Yuchung Cheng
Cc: Eric Dumazet, Alexey Kodanev, Eric Dumazet, David Miller, netdev,
Vasily Isaenko
In-Reply-To: <CAK6E8=cQdCvaXvcNzZYkC7R=vk2SmK7djS9OXNgqcWnO9CG0ug@mail.gmail.com>
On Wed, Jan 18, 2017 at 1:27 PM, Yuchung Cheng <ycheng@google.com> wrote:
> Hi Eric: yeah I think the test was just due to the TSO chunking
> difference between prod and upstream, which I was able to avoid with
> this patch re-suited by Neal in b/34128974. In fact, this patch
> enables me to run all recovery tests on upstream kernels for my RACK
> patch set.
>
> Neal: can we polish and check that in? super useful.
Yes, sounds good. Glad that was useful. I will work on polishing up
and checking in the patch to make packetdrill agnostic to TSO
segmentation by default (for upstream and Google).
neal
^ permalink raw reply
* [net-next 1/4] tipc: add function for checking broadcast support in bearer
From: Jon Maloy @ 2017-01-18 18:50 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1484765453-16258-1-git-send-email-jon.maloy@ericsson.com>
As a preparation for the 'replicast' functionality we are going to
introduce in the next commits, we need the broadcast base structure to
store whether bearer broadcast is available at all from the currently
used bearer or bearers.
We do this by adding a new function tipc_bearer_bcast_support() to
the bearer layer, and letting the bearer selection function in
bcast.c use this to give a new boolean field, 'bcast_support' the
appropriate value.
Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bcast.c | 12 +++++++++---
net/tipc/bearer.c | 15 ++++++++++++++-
net/tipc/bearer.h | 8 +++++++-
net/tipc/udp_media.c | 8 ++++----
4 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index c35fad3..3256276 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -1,7 +1,7 @@
/*
* net/tipc/bcast.c: TIPC broadcast code
*
- * Copyright (c) 2004-2006, 2014-2015, Ericsson AB
+ * Copyright (c) 2004-2006, 2014-2016, Ericsson AB
* Copyright (c) 2004, Intel Corporation.
* Copyright (c) 2005, 2010-2011, Wind River Systems
* All rights reserved.
@@ -54,12 +54,14 @@ const char tipc_bclink_name[] = "broadcast-link";
* @inputq: data input queue; will only carry SOCK_WAKEUP messages
* @dest: array keeping number of reachable destinations per bearer
* @primary_bearer: a bearer having links to all broadcast destinations, if any
+ * @bcast_support: indicates if primary bearer, if any, supports broadcast
*/
struct tipc_bc_base {
struct tipc_link *link;
struct sk_buff_head inputq;
int dests[MAX_BEARERS];
int primary_bearer;
+ bool bcast_support;
};
static struct tipc_bc_base *tipc_bc_base(struct net *net)
@@ -79,9 +81,10 @@ static void tipc_bcbase_select_primary(struct net *net)
{
struct tipc_bc_base *bb = tipc_bc_base(net);
int all_dests = tipc_link_bc_peers(bb->link);
- int i, mtu;
+ int i, mtu, prim;
bb->primary_bearer = INVALID_BEARER_ID;
+ bb->bcast_support = true;
if (!all_dests)
return;
@@ -93,7 +96,7 @@ static void tipc_bcbase_select_primary(struct net *net)
mtu = tipc_bearer_mtu(net, i);
if (mtu < tipc_link_mtu(bb->link))
tipc_link_set_mtu(bb->link, mtu);
-
+ bb->bcast_support &= tipc_bearer_bcast_support(net, i);
if (bb->dests[i] < all_dests)
continue;
@@ -103,6 +106,9 @@ static void tipc_bcbase_select_primary(struct net *net)
if ((i ^ tipc_own_addr(net)) & 1)
break;
}
+ prim = bb->primary_bearer;
+ if (prim != INVALID_BEARER_ID)
+ bb->bcast_support = tipc_bearer_bcast_support(net, prim);
}
void tipc_bcast_inc_bearer_dst_cnt(struct net *net, int bearer_id)
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 52d7476..33a5bdf 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -431,7 +431,7 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
memset(&b->bcast_addr, 0, sizeof(b->bcast_addr));
memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len);
b->bcast_addr.media_id = b->media->type_id;
- b->bcast_addr.broadcast = 1;
+ b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
b->mtu = dev->mtu;
b->media->raw2addr(b, &b->addr, (char *)dev->dev_addr);
rcu_assign_pointer(dev->tipc_ptr, b);
@@ -482,6 +482,19 @@ int tipc_l2_send_msg(struct net *net, struct sk_buff *skb,
return 0;
}
+bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id)
+{
+ bool supp = false;
+ struct tipc_bearer *b;
+
+ rcu_read_lock();
+ b = bearer_get(net, bearer_id);
+ if (b)
+ supp = (b->bcast_addr.broadcast == TIPC_BROADCAST_SUPPORT);
+ rcu_read_unlock();
+ return supp;
+}
+
int tipc_bearer_mtu(struct net *net, u32 bearer_id)
{
int mtu = 0;
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 278ff7f..635c908 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -60,9 +60,14 @@
#define TIPC_MEDIA_TYPE_IB 2
#define TIPC_MEDIA_TYPE_UDP 3
-/* minimum bearer MTU */
+/* Minimum bearer MTU */
#define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + INT_H_SIZE)
+/* Identifiers for distinguishing between broadcast/multicast and replicast
+ */
+#define TIPC_BROADCAST_SUPPORT 1
+#define TIPC_REPLICAST_SUPPORT 2
+
/**
* struct tipc_media_addr - destination address used by TIPC bearers
* @value: address info (format defined by media)
@@ -210,6 +215,7 @@ int tipc_bearer_setup(void);
void tipc_bearer_cleanup(void);
void tipc_bearer_stop(struct net *net);
int tipc_bearer_mtu(struct net *net, u32 bearer_id);
+bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id);
void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,
struct sk_buff *skb,
struct tipc_media_addr *dest);
diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
index b58dc95..46061cf 100644
--- a/net/tipc/udp_media.c
+++ b/net/tipc/udp_media.c
@@ -113,7 +113,7 @@ static void tipc_udp_media_addr_set(struct tipc_media_addr *addr,
memcpy(addr->value, ua, sizeof(struct udp_media_addr));
if (tipc_udp_is_mcast_addr(ua))
- addr->broadcast = 1;
+ addr->broadcast = TIPC_BROADCAST_SUPPORT;
}
/* tipc_udp_addr2str - convert ip/udp address to string */
@@ -229,7 +229,7 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
goto out;
}
- if (!addr->broadcast || list_empty(&ub->rcast.list))
+ if (addr->broadcast != TIPC_REPLICAST_SUPPORT)
return tipc_udp_xmit(net, skb, ub, src, dst);
/* Replicast, send an skb to each configured IP address */
@@ -296,7 +296,7 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b,
else if (ntohs(addr->proto) == ETH_P_IPV6)
pr_info("New replicast peer: %pI6\n", &rcast->addr.ipv6);
#endif
-
+ b->bcast_addr.broadcast = TIPC_REPLICAST_SUPPORT;
list_add_rcu(&rcast->list, &ub->rcast.list);
return 0;
}
@@ -681,7 +681,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
goto err;
b->bcast_addr.media_id = TIPC_MEDIA_TYPE_UDP;
- b->bcast_addr.broadcast = 1;
+ b->bcast_addr.broadcast = TIPC_BROADCAST_SUPPORT;
rcu_assign_pointer(b->media_ptr, ub);
rcu_assign_pointer(ub->bearer, b);
tipc_udp_media_addr_set(&b->addr, &local);
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 3/4] tipc: introduce replicast as transport option for multicast
From: Jon Maloy @ 2017-01-18 18:50 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1484765453-16258-1-git-send-email-jon.maloy@ericsson.com>
TIPC multicast messages are currently carried over a reliable
'broadcast link', making use of the underlying media's ability to
transport packets as L2 broadcast or IP multicast to all nodes in
the cluster.
When the used bearer is lacking that ability, we can instead emulate
the broadcast service by replicating and sending the packets over as
many unicast links as needed to reach all identified destinations.
We now introduce a new TIPC link-level 'replicast' service that does
this.
Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/tipc/bcast.c | 105 ++++++++++++++++++++++++++++++++++++++++++------------
net/tipc/bcast.h | 3 +-
net/tipc/link.c | 8 ++++-
net/tipc/msg.c | 17 +++++++++
net/tipc/msg.h | 9 +++--
net/tipc/node.c | 27 +++++++++-----
net/tipc/socket.c | 27 +++++++++-----
7 files changed, 149 insertions(+), 47 deletions(-)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 412d335..672e6ef 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -70,7 +70,7 @@ static struct tipc_bc_base *tipc_bc_base(struct net *net)
int tipc_bcast_get_mtu(struct net *net)
{
- return tipc_link_mtu(tipc_bc_sndlink(net));
+ return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE;
}
/* tipc_bcbase_select_primary(): find a bearer with links to all destinations,
@@ -175,42 +175,101 @@ static void tipc_bcbase_xmit(struct net *net, struct sk_buff_head *xmitq)
__skb_queue_purge(&_xmitq);
}
-/* tipc_bcast_xmit - deliver buffer chain to all nodes in cluster
- * and to identified node local sockets
+/* tipc_bcast_xmit - broadcast the buffer chain to all external nodes
* @net: the applicable net namespace
- * @list: chain of buffers containing message
+ * @pkts: chain of buffers containing message
+ * @cong_link_cnt: set to 1 if broadcast link is congested, otherwise 0
* Consumes the buffer chain.
- * Returns 0 if success, otherwise errno: -ELINKCONG,-EHOSTUNREACH,-EMSGSIZE
+ * Returns 0 if success, otherwise errno: -EHOSTUNREACH,-EMSGSIZE
*/
-int tipc_bcast_xmit(struct net *net, struct sk_buff_head *list)
+static int tipc_bcast_xmit(struct net *net, struct sk_buff_head *pkts,
+ u16 *cong_link_cnt)
{
struct tipc_link *l = tipc_bc_sndlink(net);
- struct sk_buff_head xmitq, inputq, rcvq;
+ struct sk_buff_head xmitq;
int rc = 0;
- __skb_queue_head_init(&rcvq);
__skb_queue_head_init(&xmitq);
- skb_queue_head_init(&inputq);
-
- /* Prepare message clone for local node */
- if (unlikely(!tipc_msg_reassemble(list, &rcvq)))
- return -EHOSTUNREACH;
-
tipc_bcast_lock(net);
if (tipc_link_bc_peers(l))
- rc = tipc_link_xmit(l, list, &xmitq);
+ rc = tipc_link_xmit(l, pkts, &xmitq);
tipc_bcast_unlock(net);
+ tipc_bcbase_xmit(net, &xmitq);
+ __skb_queue_purge(pkts);
+ if (rc == -ELINKCONG) {
+ *cong_link_cnt = 1;
+ rc = 0;
+ }
+ return rc;
+}
- /* Don't send to local node if adding to link failed */
- if (unlikely(rc && (rc != -ELINKCONG))) {
- __skb_queue_purge(&rcvq);
- return rc;
+/* tipc_rcast_xmit - replicate and send a message to given destination nodes
+ * @net: the applicable net namespace
+ * @pkts: chain of buffers containing message
+ * @dests: list of destination nodes
+ * @cong_link_cnt: returns number of congested links
+ * @cong_links: returns identities of congested links
+ * Returns 0 if success, otherwise errno
+ */
+static int tipc_rcast_xmit(struct net *net, struct sk_buff_head *pkts,
+ struct tipc_nlist *dests, u16 *cong_link_cnt)
+{
+ struct sk_buff_head _pkts;
+ struct u32_item *n, *tmp;
+ u32 dst, selector;
+
+ selector = msg_link_selector(buf_msg(skb_peek(pkts)));
+ __skb_queue_head_init(&_pkts);
+
+ list_for_each_entry_safe(n, tmp, &dests->list, list) {
+ dst = n->value;
+ if (!tipc_msg_pskb_copy(dst, pkts, &_pkts))
+ return -ENOMEM;
+
+ /* Any other return value than -ELINKCONG is ignored */
+ if (tipc_node_xmit(net, &_pkts, dst, selector) == -ELINKCONG)
+ (*cong_link_cnt)++;
}
+ return 0;
+}
- /* Broadcast to all nodes, inluding local node */
- tipc_bcbase_xmit(net, &xmitq);
- tipc_sk_mcast_rcv(net, &rcvq, &inputq);
- __skb_queue_purge(list);
+/* tipc_mcast_xmit - deliver message to indicated destination nodes
+ * and to identified node local sockets
+ * @net: the applicable net namespace
+ * @pkts: chain of buffers containing message
+ * @dests: destination nodes for message. Not consumed.
+ * @cong_link_cnt: returns number of encountered congested destination links
+ * @cong_links: returns identities of congested links
+ * Consumes buffer chain.
+ * Returns 0 if success, otherwise errno
+ */
+int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
+ struct tipc_nlist *dests, u16 *cong_link_cnt)
+{
+ struct tipc_bc_base *bb = tipc_bc_base(net);
+ struct sk_buff_head inputq, localq;
+ int rc = 0;
+
+ skb_queue_head_init(&inputq);
+ skb_queue_head_init(&localq);
+
+ /* Clone packets before they are consumed by next call */
+ if (dests->local && !tipc_msg_reassemble(pkts, &localq)) {
+ rc = -ENOMEM;
+ goto exit;
+ }
+
+ if (dests->remote) {
+ if (!bb->bcast_support)
+ rc = tipc_rcast_xmit(net, pkts, dests, cong_link_cnt);
+ else
+ rc = tipc_bcast_xmit(net, pkts, cong_link_cnt);
+ }
+
+ if (dests->local)
+ tipc_sk_mcast_rcv(net, &localq, &inputq);
+exit:
+ __skb_queue_purge(pkts);
return rc;
}
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 18f3791..dd772e6 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -66,7 +66,8 @@ void tipc_bcast_remove_peer(struct net *net, struct tipc_link *rcv_bcl);
void tipc_bcast_inc_bearer_dst_cnt(struct net *net, int bearer_id);
void tipc_bcast_dec_bearer_dst_cnt(struct net *net, int bearer_id);
int tipc_bcast_get_mtu(struct net *net);
-int tipc_bcast_xmit(struct net *net, struct sk_buff_head *list);
+int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
+ struct tipc_nlist *dests, u16 *cong_link_cnt);
int tipc_bcast_rcv(struct net *net, struct tipc_link *l, struct sk_buff *skb);
void tipc_bcast_ack_rcv(struct net *net, struct tipc_link *l,
struct tipc_msg *hdr);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index b0f8646..b17b9e1 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1032,11 +1032,17 @@ int tipc_link_retrans(struct tipc_link *l, u16 from, u16 to,
static bool tipc_data_input(struct tipc_link *l, struct sk_buff *skb,
struct sk_buff_head *inputq)
{
- switch (msg_user(buf_msg(skb))) {
+ struct tipc_msg *hdr = buf_msg(skb);
+
+ switch (msg_user(hdr)) {
case TIPC_LOW_IMPORTANCE:
case TIPC_MEDIUM_IMPORTANCE:
case TIPC_HIGH_IMPORTANCE:
case TIPC_CRITICAL_IMPORTANCE:
+ if (unlikely(msg_type(hdr) == TIPC_MCAST_MSG)) {
+ skb_queue_tail(l->bc_rcvlink->inputq, skb);
+ return true;
+ }
case CONN_MANAGER:
skb_queue_tail(inputq, skb);
return true;
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index ab02d07..312ef7d 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -607,6 +607,23 @@ bool tipc_msg_reassemble(struct sk_buff_head *list, struct sk_buff_head *rcvq)
return false;
}
+bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg,
+ struct sk_buff_head *cpy)
+{
+ struct sk_buff *skb, *_skb;
+
+ skb_queue_walk(msg, skb) {
+ _skb = pskb_copy(skb, GFP_ATOMIC);
+ if (!_skb) {
+ __skb_queue_purge(cpy);
+ return false;
+ }
+ msg_set_destnode(buf_msg(_skb), dst);
+ __skb_queue_tail(cpy, _skb);
+ }
+ return true;
+}
+
/* tipc_skb_queue_sorted(); sort pkt into list according to sequence number
* @list: list to be appended to
* @seqno: sequence number of buffer to add
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index f07b51e..c843fd2 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -631,14 +631,11 @@ static inline void msg_set_bc_netid(struct tipc_msg *m, u32 id)
static inline u32 msg_link_selector(struct tipc_msg *m)
{
+ if (msg_user(m) == MSG_FRAGMENTER)
+ m = (void *)msg_data(m);
return msg_bits(m, 4, 0, 1);
}
-static inline void msg_set_link_selector(struct tipc_msg *m, u32 n)
-{
- msg_set_bits(m, 4, 0, 1, n);
-}
-
/*
* Word 5
*/
@@ -835,6 +832,8 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
int offset, int dsz, int mtu, struct sk_buff_head *list);
bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err);
bool tipc_msg_reassemble(struct sk_buff_head *list, struct sk_buff_head *rcvq);
+bool tipc_msg_pskb_copy(u32 dst, struct sk_buff_head *msg,
+ struct sk_buff_head *cpy);
void __tipc_skb_queue_sorted(struct sk_buff_head *list, u16 seqno,
struct sk_buff *skb);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 2883f6a..f96dacf 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -1257,6 +1257,19 @@ void tipc_node_broadcast(struct net *net, struct sk_buff *skb)
kfree_skb(skb);
}
+static void tipc_node_mcast_rcv(struct tipc_node *n)
+{
+ struct tipc_bclink_entry *be = &n->bc_entry;
+
+ /* 'arrvq' is under inputq2's lock protection */
+ spin_lock_bh(&be->inputq2.lock);
+ spin_lock_bh(&be->inputq1.lock);
+ skb_queue_splice_tail_init(&be->inputq1, &be->arrvq);
+ spin_unlock_bh(&be->inputq1.lock);
+ spin_unlock_bh(&be->inputq2.lock);
+ tipc_sk_mcast_rcv(n->net, &be->arrvq, &be->inputq2);
+}
+
static void tipc_node_bc_sync_rcv(struct tipc_node *n, struct tipc_msg *hdr,
int bearer_id, struct sk_buff_head *xmitq)
{
@@ -1330,15 +1343,8 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id
if (!skb_queue_empty(&xmitq))
tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr);
- /* Deliver. 'arrvq' is under inputq2's lock protection */
- if (!skb_queue_empty(&be->inputq1)) {
- spin_lock_bh(&be->inputq2.lock);
- spin_lock_bh(&be->inputq1.lock);
- skb_queue_splice_tail_init(&be->inputq1, &be->arrvq);
- spin_unlock_bh(&be->inputq1.lock);
- spin_unlock_bh(&be->inputq2.lock);
- tipc_sk_mcast_rcv(net, &be->arrvq, &be->inputq2);
- }
+ if (!skb_queue_empty(&be->inputq1))
+ tipc_node_mcast_rcv(n);
if (rc & TIPC_LINK_DOWN_EVT) {
/* Reception reassembly failure => reset all links to peer */
@@ -1565,6 +1571,9 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b)
if (unlikely(!skb_queue_empty(&n->bc_entry.namedq)))
tipc_named_rcv(net, &n->bc_entry.namedq);
+ if (unlikely(!skb_queue_empty(&n->bc_entry.inputq1)))
+ tipc_node_mcast_rcv(n);
+
if (!skb_queue_empty(&le->inputq))
tipc_sk_rcv(net, &le->inputq);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index d2f3539..93b6ae3 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -740,32 +740,43 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
struct tipc_msg *hdr = &tsk->phdr;
struct net *net = sock_net(sk);
int mtu = tipc_bcast_get_mtu(net);
+ u32 domain = addr_domain(net, TIPC_CLUSTER_SCOPE);
struct sk_buff_head pkts;
+ struct tipc_nlist dsts;
int rc;
+ /* Block or return if any destination link is congested */
rc = tipc_wait_for_cond(sock, &timeout, !tsk->cong_link_cnt);
if (unlikely(rc))
return rc;
+ /* Lookup destination nodes */
+ tipc_nlist_init(&dsts, tipc_own_addr(net));
+ tipc_nametbl_lookup_dst_nodes(net, seq->type, seq->lower,
+ seq->upper, domain, &dsts);
+ if (!dsts.local && !dsts.remote)
+ return -EHOSTUNREACH;
+
+ /* Build message header */
msg_set_type(hdr, TIPC_MCAST_MSG);
+ msg_set_hdr_sz(hdr, MCAST_H_SIZE);
msg_set_lookup_scope(hdr, TIPC_CLUSTER_SCOPE);
msg_set_destport(hdr, 0);
msg_set_destnode(hdr, 0);
msg_set_nametype(hdr, seq->type);
msg_set_namelower(hdr, seq->lower);
msg_set_nameupper(hdr, seq->upper);
- msg_set_hdr_sz(hdr, MCAST_H_SIZE);
+ /* Build message as chain of buffers */
skb_queue_head_init(&pkts);
rc = tipc_msg_build(hdr, msg, 0, dlen, mtu, &pkts);
- if (unlikely(rc != dlen))
- return rc;
- rc = tipc_bcast_xmit(net, &pkts);
- if (unlikely(rc == -ELINKCONG)) {
- tsk->cong_link_cnt = 1;
- rc = 0;
- }
+ /* Send message if build was successful */
+ if (unlikely(rc == dlen))
+ rc = tipc_mcast_xmit(net, &pkts, &dsts,
+ &tsk->cong_link_cnt);
+
+ tipc_nlist_purge(&dsts);
return rc ? rc : dlen;
}
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
^ permalink raw reply related
* [net-next 4/4] tipc: make replicast a user selectable option
From: Jon Maloy @ 2017-01-18 18:50 UTC (permalink / raw)
To: davem; +Cc: Jon Maloy, netdev, tipc-discussion
In-Reply-To: <1484765453-16258-1-git-send-email-jon.maloy@ericsson.com>
If the bearer carrying multicast messages supports broadcast, those
messages will be sent to all cluster nodes, irrespective of whether
these nodes host any actual destinations socket or not. This is clearly
wasteful if the cluster is large and there are only a few real
destinations for the message being sent.
In this commit we extend the eligibility of the newly introduced
"replicast" transmit option. We now make it possible for a user to
select which method he wants to be used, either as a mandatory setting
via setsockopt(), or as a relative setting where we let the broadcast
layer decide which method to use based on the ratio between cluster
size and the message's actual number of destination nodes.
In the latter case, a sending socket must stick to a previously
selected method until it enters an idle period of at least 5 seconds.
This eliminates the risk of message reordering caused by method change,
i.e., when changes to cluster size or number of destinations would
otherwise mandate a new method to be used.
Reviewed-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
---
include/uapi/linux/tipc.h | 6 +++--
net/tipc/bcast.c | 62 ++++++++++++++++++++++++++++++++++++++++++-----
net/tipc/bcast.h | 17 ++++++++++++-
net/tipc/link.c | 4 +++
net/tipc/node.h | 4 ++-
net/tipc/socket.c | 36 +++++++++++++++++++++------
6 files changed, 112 insertions(+), 17 deletions(-)
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index bf049e8..5351b08 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -1,7 +1,7 @@
/*
* include/uapi/linux/tipc.h: Header for TIPC socket interface
*
- * Copyright (c) 2003-2006, Ericsson AB
+ * Copyright (c) 2003-2006, 2015-2016 Ericsson AB
* Copyright (c) 2005, 2010-2011, Wind River Systems
* All rights reserved.
*
@@ -220,7 +220,7 @@ struct sockaddr_tipc {
#define TIPC_DESTNAME 3 /* destination name */
/*
- * TIPC-specific socket option values
+ * TIPC-specific socket option names
*/
#define TIPC_IMPORTANCE 127 /* Default: TIPC_LOW_IMPORTANCE */
@@ -229,6 +229,8 @@ struct sockaddr_tipc {
#define TIPC_CONN_TIMEOUT 130 /* Default: 8000 (ms) */
#define TIPC_NODE_RECVQ_DEPTH 131 /* Default: none (read only) */
#define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */
+#define TIPC_MCAST_BROADCAST 133 /* Default: TIPC selects. No arg */
+#define TIPC_MCAST_REPLICAST 134 /* Default: TIPC selects. No arg */
/*
* Maximum sizes of TIPC bearer-related names (including terminating NULL)
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 672e6ef..7d99029 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -54,6 +54,9 @@ const char tipc_bclink_name[] = "broadcast-link";
* @dest: array keeping number of reachable destinations per bearer
* @primary_bearer: a bearer having links to all broadcast destinations, if any
* @bcast_support: indicates if primary bearer, if any, supports broadcast
+ * @rcast_support: indicates if all peer nodes support replicast
+ * @rc_ratio: dest count as percentage of cluster size where send method changes
+ * @bc_threshold: calculated drom rc_ratio; if dests > threshold use broadcast
*/
struct tipc_bc_base {
struct tipc_link *link;
@@ -61,6 +64,9 @@ struct tipc_bc_base {
int dests[MAX_BEARERS];
int primary_bearer;
bool bcast_support;
+ bool rcast_support;
+ int rc_ratio;
+ int bc_threshold;
};
static struct tipc_bc_base *tipc_bc_base(struct net *net)
@@ -73,6 +79,19 @@ int tipc_bcast_get_mtu(struct net *net)
return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE;
}
+void tipc_bcast_disable_rcast(struct net *net)
+{
+ tipc_bc_base(net)->rcast_support = false;
+}
+
+static void tipc_bcbase_calc_bc_threshold(struct net *net)
+{
+ struct tipc_bc_base *bb = tipc_bc_base(net);
+ int cluster_size = tipc_link_bc_peers(tipc_bc_sndlink(net));
+
+ bb->bc_threshold = 1 + (cluster_size * bb->rc_ratio / 100);
+}
+
/* tipc_bcbase_select_primary(): find a bearer with links to all destinations,
* if any, and make it primary bearer
*/
@@ -175,6 +194,31 @@ static void tipc_bcbase_xmit(struct net *net, struct sk_buff_head *xmitq)
__skb_queue_purge(&_xmitq);
}
+static void tipc_bcast_select_xmit_method(struct net *net, int dests,
+ struct tipc_mc_method *method)
+{
+ struct tipc_bc_base *bb = tipc_bc_base(net);
+ unsigned long exp = method->expires;
+
+ /* Broadcast supported by used bearer/bearers? */
+ if (!bb->bcast_support) {
+ method->rcast = true;
+ return;
+ }
+ /* Any destinations which don't support replicast ? */
+ if (!bb->rcast_support) {
+ method->rcast = false;
+ return;
+ }
+ /* Can current method be changed ? */
+ method->expires = jiffies + TIPC_METHOD_EXPIRE;
+ if (method->mandatory || time_before(jiffies, exp))
+ return;
+
+ /* Determine method to use now */
+ method->rcast = dests <= bb->bc_threshold;
+}
+
/* tipc_bcast_xmit - broadcast the buffer chain to all external nodes
* @net: the applicable net namespace
* @pkts: chain of buffers containing message
@@ -237,16 +281,16 @@ static int tipc_rcast_xmit(struct net *net, struct sk_buff_head *pkts,
* and to identified node local sockets
* @net: the applicable net namespace
* @pkts: chain of buffers containing message
- * @dests: destination nodes for message. Not consumed.
+ * @method: send method to be used
+ * @dests: destination nodes for message.
* @cong_link_cnt: returns number of encountered congested destination links
- * @cong_links: returns identities of congested links
* Consumes buffer chain.
* Returns 0 if success, otherwise errno
*/
int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
- struct tipc_nlist *dests, u16 *cong_link_cnt)
+ struct tipc_mc_method *method, struct tipc_nlist *dests,
+ u16 *cong_link_cnt)
{
- struct tipc_bc_base *bb = tipc_bc_base(net);
struct sk_buff_head inputq, localq;
int rc = 0;
@@ -258,9 +302,10 @@ int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
rc = -ENOMEM;
goto exit;
}
-
+ /* Send according to determined transmit method */
if (dests->remote) {
- if (!bb->bcast_support)
+ tipc_bcast_select_xmit_method(net, dests->remote, method);
+ if (method->rcast)
rc = tipc_rcast_xmit(net, pkts, dests, cong_link_cnt);
else
rc = tipc_bcast_xmit(net, pkts, cong_link_cnt);
@@ -269,6 +314,7 @@ int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
if (dests->local)
tipc_sk_mcast_rcv(net, &localq, &inputq);
exit:
+ /* This queue should normally be empty by now */
__skb_queue_purge(pkts);
return rc;
}
@@ -377,6 +423,7 @@ void tipc_bcast_add_peer(struct net *net, struct tipc_link *uc_l,
tipc_bcast_lock(net);
tipc_link_add_bc_peer(snd_l, uc_l, xmitq);
tipc_bcbase_select_primary(net);
+ tipc_bcbase_calc_bc_threshold(net);
tipc_bcast_unlock(net);
}
@@ -395,6 +442,7 @@ void tipc_bcast_remove_peer(struct net *net, struct tipc_link *rcv_l)
tipc_bcast_lock(net);
tipc_link_remove_bc_peer(snd_l, rcv_l, &xmitq);
tipc_bcbase_select_primary(net);
+ tipc_bcbase_calc_bc_threshold(net);
tipc_bcast_unlock(net);
tipc_bcbase_xmit(net, &xmitq);
@@ -477,6 +525,8 @@ int tipc_bcast_init(struct net *net)
goto enomem;
bb->link = l;
tn->bcl = l;
+ bb->rc_ratio = 25;
+ bb->rcast_support = true;
return 0;
enomem:
kfree(bb);
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index dd772e6..751530a 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -46,6 +46,8 @@ struct tipc_nlist;
struct tipc_nitem;
extern const char tipc_bclink_name[];
+#define TIPC_METHOD_EXPIRE msecs_to_jiffies(5000)
+
struct tipc_nlist {
struct list_head list;
u32 self;
@@ -58,6 +60,17 @@ void tipc_nlist_purge(struct tipc_nlist *nl);
void tipc_nlist_add(struct tipc_nlist *nl, u32 node);
void tipc_nlist_del(struct tipc_nlist *nl, u32 node);
+/* Cookie to be used between socket and broadcast layer
+ * @rcast: replicast (instead of broadcast) was used at previous xmit
+ * @mandatory: broadcast/replicast indication was set by user
+ * @expires: re-evaluate non-mandatory transmit method if we are past this
+ */
+struct tipc_mc_method {
+ bool rcast;
+ bool mandatory;
+ unsigned long expires;
+};
+
int tipc_bcast_init(struct net *net);
void tipc_bcast_stop(struct net *net);
void tipc_bcast_add_peer(struct net *net, struct tipc_link *l,
@@ -66,8 +79,10 @@ void tipc_bcast_remove_peer(struct net *net, struct tipc_link *rcv_bcl);
void tipc_bcast_inc_bearer_dst_cnt(struct net *net, int bearer_id);
void tipc_bcast_dec_bearer_dst_cnt(struct net *net, int bearer_id);
int tipc_bcast_get_mtu(struct net *net);
+void tipc_bcast_disable_rcast(struct net *net);
int tipc_mcast_xmit(struct net *net, struct sk_buff_head *pkts,
- struct tipc_nlist *dests, u16 *cong_link_cnt);
+ struct tipc_mc_method *method, struct tipc_nlist *dests,
+ u16 *cong_link_cnt);
int tipc_bcast_rcv(struct net *net, struct tipc_link *l, struct sk_buff *skb);
void tipc_bcast_ack_rcv(struct net *net, struct tipc_link *l,
struct tipc_msg *hdr);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index b17b9e1..ddd2dd6f 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -515,6 +515,10 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer,
if (link_is_bc_sndlink(l))
l->state = LINK_ESTABLISHED;
+ /* Disable replicast if even a single peer doesn't support it */
+ if (link_is_bc_rcvlink(l) && !(peer_caps & TIPC_BCAST_RCAST))
+ tipc_bcast_disable_rcast(net);
+
return true;
}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 39ef54c..898c229 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -47,11 +47,13 @@
enum {
TIPC_BCAST_SYNCH = (1 << 1),
TIPC_BCAST_STATE_NACK = (1 << 2),
- TIPC_BLOCK_FLOWCTL = (1 << 3)
+ TIPC_BLOCK_FLOWCTL = (1 << 3),
+ TIPC_BCAST_RCAST = (1 << 4)
};
#define TIPC_NODE_CAPABILITIES (TIPC_BCAST_SYNCH | \
TIPC_BCAST_STATE_NACK | \
+ TIPC_BCAST_RCAST | \
TIPC_BLOCK_FLOWCTL)
#define INVALID_BEARER_ID -1
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 93b6ae3..5bec8aa 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -79,6 +79,7 @@ enum {
* @rcv_unacked: # messages read by user, but not yet acked back to peer
* @peer: 'connected' peer for dgram/rdm
* @node: hash table node
+ * @mc_method: cookie for use between socket and broadcast layer
* @rcu: rcu struct for tipc_sock
*/
struct tipc_sock {
@@ -103,6 +104,7 @@ struct tipc_sock {
u16 rcv_win;
struct sockaddr_tipc peer;
struct rhash_head node;
+ struct tipc_mc_method mc_method;
struct rcu_head rcu;
};
@@ -740,6 +742,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
struct tipc_msg *hdr = &tsk->phdr;
struct net *net = sock_net(sk);
int mtu = tipc_bcast_get_mtu(net);
+ struct tipc_mc_method *method = &tsk->mc_method;
u32 domain = addr_domain(net, TIPC_CLUSTER_SCOPE);
struct sk_buff_head pkts;
struct tipc_nlist dsts;
@@ -773,7 +776,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
/* Send message if build was successful */
if (unlikely(rc == dlen))
- rc = tipc_mcast_xmit(net, &pkts, &dsts,
+ rc = tipc_mcast_xmit(net, &pkts, method, &dsts,
&tsk->cong_link_cnt);
tipc_nlist_purge(&dsts);
@@ -2344,18 +2347,29 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
{
struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
- u32 value;
+ u32 value = 0;
int res;
if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
return 0;
if (lvl != SOL_TIPC)
return -ENOPROTOOPT;
- if (ol < sizeof(value))
- return -EINVAL;
- res = get_user(value, (u32 __user *)ov);
- if (res)
- return res;
+
+ switch (opt) {
+ case TIPC_IMPORTANCE:
+ case TIPC_SRC_DROPPABLE:
+ case TIPC_DEST_DROPPABLE:
+ case TIPC_CONN_TIMEOUT:
+ if (ol < sizeof(value))
+ return -EINVAL;
+ res = get_user(value, (u32 __user *)ov);
+ if (res)
+ return res;
+ break;
+ default:
+ if (ov || ol)
+ return -EINVAL;
+ }
lock_sock(sk);
@@ -2376,6 +2390,14 @@ static int tipc_setsockopt(struct socket *sock, int lvl, int opt,
tipc_sk(sk)->conn_timeout = value;
/* no need to set "res", since already 0 at this point */
break;
+ case TIPC_MCAST_BROADCAST:
+ tsk->mc_method.rcast = false;
+ tsk->mc_method.mandatory = true;
+ break;
+ case TIPC_MCAST_REPLICAST:
+ tsk->mc_method.rcast = true;
+ tsk->mc_method.mandatory = true;
+ break;
default:
res = -EINVAL;
}
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
^ 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