Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next V5 3/3] tun: rx batching
From: Jason Wang @ 2017-01-18  7:02 UTC (permalink / raw)
  To: mst, virtualization, netdev, kvm; +Cc: wexu, stefanha
In-Reply-To: <1484722923-7698-1-git-send-email-jasowang@redhat.com>

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>
---
 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 related

* Re: [PATCH net-next v3 06/10] net: dsa: Migrate to device_find_class()
From: Greg KH @ 2017-01-18  7:06 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Andrew Lunn, Jason Cooper, Vivien Didelot, netdev, Russell King,
	open list, Gregory Clement, David S. Miller,
	moderated list:ARM SUB-ARCHITECTURES, Sebastian Hesselbarth
In-Reply-To: <912e6143-c67a-d909-2a6c-939de79efc5d@gmail.com>

On Mon, Jan 16, 2017 at 12:01:02PM -0800, Florian Fainelli wrote:
> On 01/15/2017 11:16 AM, Andrew Lunn wrote:
> >>> What exactly is the relationship between these devices (a ascii-art tree
> >>> or sysfs tree output might be nice) so I can try to understand what is
> >>> going on here.
> > 
> > Hi Greg, Florian
> > 
> > A few diagrams and trees which might help understand what is going on.
> > 
> > The first diagram comes from the 2008 patch which added all this code:
> > 
> >             +-----------+       +-----------+
> >             |           | RGMII |           |
> >             |           +-------+           +------ 1000baseT MDI ("WAN")
> >             |           |       |  6-port   +------ 1000baseT MDI ("LAN1")
> >             |    CPU    |       |  ethernet +------ 1000baseT MDI ("LAN2")
> >             |           |MIImgmt|  switch   +------ 1000baseT MDI ("LAN3")
> >             |           +-------+  w/5 PHYs +------ 1000baseT MDI ("LAN4")
> >             |           |       |           |
> >             +-----------+       +-----------+
> > 
> > We have an ethernet switch and a host CPU. The switch is connected to
> > the CPU in two different ways. RGMII allows us to get Ethernet frames
> > from the CPU into the switch. MIImgmt, is the management bus normally
> > used for Ethernet PHYs, but Marvell switches also use it for Managing
> > switches.
> > 
> > The diagram above is the simplest setup. You can have multiple
> > Ethernet switches, connected together via switch ports. Each switch
> > has its own MIImgmt connect to the CPU, but there is only one RGMII
> > link.
> > 
> > When this code was designed back in 2008, it was decided to represent
> > this is a platform device, and it has a platform_data, which i have
> > slightly edited to keep it simple:
> > 
> > struct dsa_platform_data {
> >         /*
> >          * Reference to a Linux network interface that connects
> >          * to the root switch chip of the tree.
> >          */
> >         struct device   *netdev;
> > 
> >         /*
> >          * Info structs describing each of the switch chips
> >          * connected via this network interface.
> >          */
> >         int             nr_chips;
> >         struct dsa_chip_data    *chip;
> > };
> > 
> > This netdev is the CPU side of the RGMII interface.
> > 
> > Each switch has a dsa_chip_data, again edited:
> > 
> > struct dsa_chip_data {
> >         /*
> >          * How to access the switch configuration registers.
> >          */
> >         struct device   *host_dev;
> >         int             sw_addr;
> > ...
> > }
> > 
> > The host_dev is the CPU side of the MIImgmt, and we have the address
> > the switch is using on the bus.
> > 
> > During probe of this platform device, we need to get from the
> > struct device *netdev to a struct net_device *dev.
> > 
> > So the code looks in the device net class to find the device
> > 
> > |   |   |   |-- f1074000.ethernet
> > |   |   |   |   |-- deferred_probe
> > |   |   |   |   |-- driver -> ../../../../../bus/platform/drivers/mvneta
> > |   |   |   |   |-- driver_override
> > |   |   |   |   |-- modalias
> > |   |   |   |   |-- net
> > |   |   |   |   |   `-- eth1
> > |   |   |   |   |       |-- addr_assign_type
> > |   |   |   |   |       |-- address
> > |   |   |   |   |       |-- addr_len
> > |   |   |   |   |       |-- broadcast
> > |   |   |   |   |       |-- carrier
> > |   |   |   |   |       |-- carrier_changes
> > |   |   |   |   |       |-- deferred_probe
> > |   |   |   |   |       |-- device -> ../../../f1074000.ethernet
> > 
> > and then use container_of() to get the net_device.
> > 
> > Similarly, the code needs to get from struct device *host_dev to a struct mii_bus *.
> > 
> > |   |   |   |-- f1072004.mdio
> > |   |   |   |   |-- deferred_probe
> > |   |   |   |   |-- driver -> ../../../../../bus/platform/drivers/orion-mdio
> > |   |   |   |   |-- driver_override
> > |   |   |   |   |-- mdio_bus
> > |   |   |   |   |   `-- f1072004.mdio-mi
> > |   |   |   |   |       |-- deferred_probe
> > |   |   |   |   |       |-- device -> ../../../f1072004.mdio
> > 
> 
> Thanks Andrew! Greg, does that make it clearer how these devices
> references are used, do you still think the way this is done is wrong,
> too cautious, or valid?

I'm still not sold on it, I think there is something odd here with your
use/assumptions of the driver model.  Give me a few days to catch up
with other stuff to respond back please...

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH net-next v4 05/10] drivers: base: Add device_find_in_class_name()
From: Greg Kroah-Hartman @ 2017-01-18  7:06 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Andrew Lunn, Jason Cooper, Vivien Didelot, netdev, Russell King,
	open list, Gregory Clement, David S. Miller,
	moderated list:ARM/Marvell Dove/MV78xx0/Orion SOC support,
	Sebastian Hesselbarth
In-Reply-To: <20170117232152.1661-6-f.fainelli@gmail.com>

On Tue, Jan 17, 2017 at 03:21:47PM -0800, Florian Fainelli wrote:
> Add a helper function to lookup a device reference given a class name.
> This is a preliminary patch to remove adhoc code from net/dsa/dsa.c and
> make it more generic.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
>  drivers/base/core.c    | 31 +++++++++++++++++++++++++++++++
>  include/linux/device.h |  2 ++
>  2 files changed, 33 insertions(+)

My NAK still stands here, please give me a day or so to respond to the
other thread about this...

thanks,

greg k-h

^ permalink raw reply

* Re: [PATCH RFC ipsec-next] IPsec offload, part one
From: Steffen Klassert @ 2017-01-18  7:59 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: Sowmini Varadhan, Ilan Tayari
In-Reply-To: <1483518230-6777-1-git-send-email-steffen.klassert@secunet.com>

On Wed, Jan 04, 2017 at 09:23:45AM +0100, Steffen Klassert wrote:
> This is the first part of the IPsec offload work we
> talked at the IPsec workshop at the last netdev
> conference. I plan to apply this to ipsec-next
> after this round of review.
> 
> Patch 1 and 2 try to avoid skb linearization in
> the ESP layer.
> 
> Patch 3 introduces a hepler to seup the esp trailer.

I have not received any comments about patches 1-3,
so I've applied them to ipsec-next.

> 
> Patch 4 prepares the generic network code for
> IPsec GRO. The main reason why we need this, is
> that we need to reinject the decrypted inner
> packet back to the GRO layer.
> 
> Patch 5 introduces GRO handlers for ESP, GRO
> can enabled with a IPsec offload config option.
> This config option will also be used for the
> upcomming hardware offload.

Patches 4 and 5 will be refactored according to
the comments from Eric.

^ permalink raw reply

* Re: [PATCH] ip/xfrm: Fix deleteall when having many policies installed
From: Alexander Heinlein @ 2017-01-18  8:00 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20170117084412.0bff48bb@xeon-e3>

On 01/17/2017 05:44 PM, Stephen Hemminger wrote:
> What happens when many many policies are installed?
> It looks like your patch would silently stop deleting.
> Does the the code flush all of them?

Yes, it flushes all of them. xfrm_policy_list_or_deleteall() performs
multiple rounds until there are no more policies left to delete
(xb.nlmsg_count becomes 0).

The previous code failed with
> Policy buffer overflow
> Delete-all terminated
upon reaching the end of the buffer. This already happens for 102
policies on my system.

The new code fills the buffer, sends the corresponding netlink message
and then re-checks for remaining policies to delete.

You can check the old and new behavior via the following commands:
# for((i=0;i<255;++i)); do ip x p a src 0.0.0.$i dst 127.0.0.0/24 dev lo
dir out action allow priority 10000; done
# ip -s -s x p deleteall action allow priority 10000

Regards
Alex

^ permalink raw reply

* Re: [PATCH for bnxt_re V4 10/21] RDMA/bnxt_re: Support for CQ verbs
From: Leon Romanovsky @ 2017-01-18  8:19 UTC (permalink / raw)
  To: Selvin Xavier
  Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
	michael.chan-dY08KVG/lbpWk0Htik3J/w, Eddie Wai, Devesh Sharma,
	Somnath Kotur, Sriharsha Basavapatna
In-Reply-To: <1482320530-5344-11-git-send-email-selvin.xavier-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 3910 bytes --]

On Wed, Dec 21, 2016 at 03:41:59AM -0800, Selvin Xavier wrote:
> Implements support for create_cq, destroy_cq and req_notify_cq
> verbs.
>
> v3: Code cleanup based on errors reported by sparse on endianness check.
>     Removes unwanted macros.
>
> Signed-off-by: Eddie Wai <eddie.wai-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Devesh Sharma <devesh.sharma-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Somnath Kotur <somnath.kotur-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> Signed-off-by: Selvin Xavier <selvin.xavier-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
> ---
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c | 146 +++++++++++++++++++++++++
>  drivers/infiniband/hw/bnxt_re/ib_verbs.h |  19 ++++
>  drivers/infiniband/hw/bnxt_re/main.c     |   4 +
>  drivers/infiniband/hw/bnxt_re/qplib_fp.c | 181 +++++++++++++++++++++++++++++++
>  drivers/infiniband/hw/bnxt_re/qplib_fp.h |  50 +++++++++
>  include/uapi/rdma/bnxt_re-abi.h          |  12 ++
>  6 files changed, 412 insertions(+)
>
> diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> index b09c2cb..e12e0c2 100644
> --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c
> @@ -492,6 +492,152 @@ struct ib_pd *bnxt_re_alloc_pd(struct ib_device *ibdev,
>  	return ERR_PTR(rc);
>  }
>
> +/* Completion Queues */
> +int bnxt_re_destroy_cq(struct ib_cq *ib_cq)
> +{
> +	struct bnxt_re_cq *cq = container_of(ib_cq, struct bnxt_re_cq, ib_cq);
> +	struct bnxt_re_dev *rdev = cq->rdev;
> +	int rc;
> +
> +	rc = bnxt_qplib_destroy_cq(&rdev->qplib_res, &cq->qplib_cq);
> +	if (rc) {
> +		dev_err(rdev_to_dev(rdev), "Failed to destroy HW CQ");
> +		return rc;
> +	}
> +	if (cq->umem && !IS_ERR(cq->umem))
> +		ib_umem_release(cq->umem);
> +
> +	if (cq) {
> +		kfree(cq->cql);
> +		kfree(cq);
> +	}
> +	atomic_dec(&rdev->cq_count);
> +	rdev->nq.budget--;
> +	return 0;
> +}
> +
> +struct ib_cq *bnxt_re_create_cq(struct ib_device *ibdev,
> +				const struct ib_cq_init_attr *attr,
> +				struct ib_ucontext *context,
> +				struct ib_udata *udata)
> +{
> +	struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
> +	struct bnxt_qplib_dev_attr *dev_attr = &rdev->dev_attr;
> +	struct bnxt_re_cq *cq = NULL;
> +	int rc, entries;
> +	int cqe = attr->cqe;
> +
> +	/* Validate CQ fields */
> +	if (cqe < 1 || cqe > dev_attr->max_cq_wqes) {
> +		dev_err(rdev_to_dev(rdev), "Failed to create CQ -max exceeded");
> +		return ERR_PTR(-EINVAL);
> +	}
> +	cq = kzalloc(sizeof(*cq), GFP_KERNEL);
> +	if (!cq)
> +		return ERR_PTR(-ENOMEM);
> +
> +	cq->rdev = rdev;
> +	cq->qplib_cq.cq_handle = (u64)(unsigned long)(&cq->qplib_cq);
> +
> +	entries = roundup_pow_of_two(cqe + 1);
> +	if (entries > dev_attr->max_cq_wqes + 1)
> +		entries = dev_attr->max_cq_wqes + 1;
> +
> +	if (context) {
> +		struct bnxt_re_cq_req req;
> +		struct bnxt_re_ucontext *uctx = container_of
> +						(context,
> +						 struct bnxt_re_ucontext,
> +						 ib_uctx);
> +		if (ib_copy_from_udata(&req, udata, sizeof(req))) {
> +			rc = -EFAULT;
> +			goto fail;
> +		}
> +
> +		cq->umem = ib_umem_get(context, req.cq_va,
> +				       entries * sizeof(struct cq_base),
> +				       IB_ACCESS_LOCAL_WRITE, 1);
> +		if (IS_ERR(cq->umem)) {
> +			rc = PTR_ERR(cq->umem);
> +			goto fail;
> +		}
> +		cq->qplib_cq.sghead = cq->umem->sg_head.sgl;
> +		cq->qplib_cq.nmap = cq->umem->nmap;
> +		cq->qplib_cq.dpi = uctx->dpi;
> +	} else {
> +		cq->max_cql = entries > MAX_CQL_PER_POLL ? MAX_CQL_PER_POLL :
> +					entries;

It is better to use already existing macros - min()
cq->max_cql = min(entries, MAX_CQL_PER_POLL);

I afraid that you can't avoid the respinning, you have more than month
till merge window.

Can you please remove useless wrappers and try to reuse kernel macros?

Thanks

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH for bnxt_re V4 10/21] RDMA/bnxt_re: Support for CQ verbs
From: Selvin Xavier @ 2017-01-18  9:12 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: Doug Ledford, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	Linux Netdev List, Michael Chan, Eddie Wai, Devesh Sharma,
	Somnath Kotur, Sriharsha Basavapatna

On Wed, Jan 18, 2017 at 1:49 PM, Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> It is better to use already existing macros - min()
> cq->max_cql = min(entries, MAX_CQL_PER_POLL);
>
> I afraid that you can't avoid the respinning, you have more than month
> till merge window.
>
> Can you please remove useless wrappers and try to reuse kernel macros?

Leon,
  Thanks for your comments. I will include your both comments in the
next patch set.

Doug,
   Is it ok if I send out the V5 now after re-basing against for-4.11
branch or should i wait for your comments on V4?

Thanks,
Selvin
--
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 for bnxt_re V4 13/21] RDMA/bnxt_re: Support QP verbs
From: Leon Romanovsky @ 2017-01-18  9:16 UTC (permalink / raw)
  To: Selvin Xavier
  Cc: dledford, linux-rdma, netdev, michael.chan, Eddie Wai,
	Devesh Sharma, Somnath Kotur, Sriharsha Basavapatna
In-Reply-To: <1482320530-5344-14-git-send-email-selvin.xavier@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 3230 bytes --]

On Wed, Dec 21, 2016 at 03:42:02AM -0800, Selvin Xavier wrote:
> This patch implements create_qp, destroy_qp, query_qp and modify_qp verbs.
>
> v2: Fixed sparse warnings
> v3: Splits __filter_modify_flags function to avoid nested switch cases.
>     Removes unwanted macros. Also, fix the endianness related issues
>     reported by sparse.
>
> Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
> Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> ---

<snip>

> +
> +static u8 __from_ib_qp_type(enum ib_qp_type type)
> +{
> +	switch (type) {
> +	case IB_QPT_GSI:
> +		return CMDQ_CREATE_QP1_TYPE_GSI;
> +	case IB_QPT_RC:
> +		return CMDQ_CREATE_QP_TYPE_RC;
> +	case IB_QPT_UD:
> +		return CMDQ_CREATE_QP_TYPE_UD;
> +	case IB_QPT_RAW_ETHERTYPE:
> +		return CMDQ_CREATE_QP_TYPE_RAW_ETHERTYPE;
> +	default:
> +		return IB_QPT_MAX;
> +	}
> +}
> +

<snip>

> +static u8 __from_ib_qp_state(enum ib_qp_state state)
> +{
> +	switch (state) {
> +	case IB_QPS_RESET:
> +		return CMDQ_MODIFY_QP_NEW_STATE_RESET;
> +	case IB_QPS_INIT:
> +		return CMDQ_MODIFY_QP_NEW_STATE_INIT;
> +	case IB_QPS_RTR:
> +		return CMDQ_MODIFY_QP_NEW_STATE_RTR;
> +	case IB_QPS_RTS:
> +		return CMDQ_MODIFY_QP_NEW_STATE_RTS;
> +	case IB_QPS_SQD:
> +		return CMDQ_MODIFY_QP_NEW_STATE_SQD;
> +	case IB_QPS_SQE:
> +		return CMDQ_MODIFY_QP_NEW_STATE_SQE;
> +	case IB_QPS_ERR:
> +	default:
> +		return CMDQ_MODIFY_QP_NEW_STATE_ERR;
> +	}
> +}
> +
> +static enum ib_qp_state __to_ib_qp_state(u8 state)
> +{
> +	switch (state) {
> +	case CMDQ_MODIFY_QP_NEW_STATE_RESET:
> +		return IB_QPS_RESET;
> +	case CMDQ_MODIFY_QP_NEW_STATE_INIT:
> +		return IB_QPS_INIT;
> +	case CMDQ_MODIFY_QP_NEW_STATE_RTR:
> +		return IB_QPS_RTR;
> +	case CMDQ_MODIFY_QP_NEW_STATE_RTS:
> +		return IB_QPS_RTS;
> +	case CMDQ_MODIFY_QP_NEW_STATE_SQD:
> +		return IB_QPS_SQD;
> +	case CMDQ_MODIFY_QP_NEW_STATE_SQE:
> +		return IB_QPS_SQE;
> +	case CMDQ_MODIFY_QP_NEW_STATE_ERR:
> +	default:
> +		return IB_QPS_ERR;
> +	}
> +}
> +
> +static u32 __from_ib_mtu(enum ib_mtu mtu)
> +{
> +	switch (mtu) {
> +	case IB_MTU_256:
> +		return CMDQ_MODIFY_QP_PATH_MTU_MTU_256;
> +	case IB_MTU_512:
> +		return CMDQ_MODIFY_QP_PATH_MTU_MTU_512;
> +	case IB_MTU_1024:
> +		return CMDQ_MODIFY_QP_PATH_MTU_MTU_1024;
> +	case IB_MTU_2048:
> +		return CMDQ_MODIFY_QP_PATH_MTU_MTU_2048;
> +	case IB_MTU_4096:
> +		return CMDQ_MODIFY_QP_PATH_MTU_MTU_4096;
> +	default:
> +		return CMDQ_MODIFY_QP_PATH_MTU_MTU_2048;
> +	}
> +}
> +
> +static enum ib_mtu __to_ib_mtu(u32 mtu)
> +{
> +	switch (mtu & CREQ_QUERY_QP_RESP_SB_PATH_MTU_MASK) {
> +	case CMDQ_MODIFY_QP_PATH_MTU_MTU_256:
> +		return IB_MTU_256;
> +	case CMDQ_MODIFY_QP_PATH_MTU_MTU_512:
> +		return IB_MTU_512;
> +	case CMDQ_MODIFY_QP_PATH_MTU_MTU_1024:
> +		return IB_MTU_1024;
> +	case CMDQ_MODIFY_QP_PATH_MTU_MTU_2048:
> +		return IB_MTU_2048;
> +	case CMDQ_MODIFY_QP_PATH_MTU_MTU_4096:
> +		return IB_MTU_4096;
> +	default:
> +		return IB_MTU_2048;
> +	}
> +}

Why do you you need these functions? These translations to<->from look
redundant.

Thanks

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: fs, net: deadlock between bind/splice on af_unix
From: Dmitry Vyukov @ 2017-01-18  9:17 UTC (permalink / raw)
  To: Cong Wang
  Cc: Al Viro, linux-fsdevel@vger.kernel.org, LKML, David Miller,
	Rainer Weikusat, Hannes Frederic Sowa, netdev, Eric Dumazet,
	syzkaller
In-Reply-To: <CAM_iQpWu+V2E_uxJLUjS+xM+94CKKR+Bv95UrFPuswUAuAGM+w@mail.gmail.com>

On Tue, Jan 17, 2017 at 10:21 PM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Mon, Jan 16, 2017 at 1:32 AM, Dmitry Vyukov <dvyukov@google.com> wrote:
>> On Fri, Dec 9, 2016 at 7:41 AM, Al Viro <viro@zeniv.linux.org.uk> wrote:
>>> On Thu, Dec 08, 2016 at 10:32:00PM -0800, Cong Wang wrote:
>>>
>>>> > Why do we do autobind there, anyway, and why is it conditional on
>>>> > SOCK_PASSCRED?  Note that e.g. for SOCK_STREAM we can bloody well get
>>>> > to sending stuff without autobind ever done - just use socketpair()
>>>> > to create that sucker and we won't be going through the connect()
>>>> > at all.
>>>>
>>>> In the case Dmitry reported, unix_dgram_sendmsg() calls unix_autobind(),
>>>> not SOCK_STREAM.
>>>
>>> Yes, I've noticed.  What I'm asking is what in there needs autobind triggered
>>> on sendmsg and why doesn't the same need affect the SOCK_STREAM case?
>>>
>>>> I guess some lock, perhaps the u->bindlock could be dropped before
>>>> acquiring the next one (sb_writer), but I need to double check.
>>>
>>> Bad idea, IMO - do you *want* autobind being able to come through while
>>> bind(2) is busy with mknod?
>>
>>
>> Ping. This is still happening on HEAD.
>>
>
> Thanks for your reminder. Mind to give the attached patch (compile only)
> a try? I take another approach to fix this deadlock, which moves the
> unix_mknod() out of unix->bindlock. Not sure if there is any unexpected
> impact with this way.


I instantly hit:

general protection fault: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
   (ftrace buffer empty)
Modules linked in:
CPU: 0 PID: 8930 Comm: syz-executor1 Not tainted 4.10.0-rc4+ #177
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
task: ffff88003c908840 task.stack: ffff88003a9a0000
RIP: 0010:__lock_acquire+0xb3a/0x3430 kernel/locking/lockdep.c:3224
RSP: 0018:ffff88003a9a7218 EFLAGS: 00010006
RAX: dffffc0000000000 RBX: dffffc0000000000 RCX: 0000000000000000
RDX: 0000000000000003 RSI: 0000000000000000 RDI: 1ffff10007534e9d
RBP: ffff88003a9a7750 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000018 R11: 0000000000000000 R12: ffff88003c908840
R13: 0000000000000001 R14: ffffffff863504a0 R15: 0000000000000001
FS:  00007f4f8eb5d700(0000) GS:ffff88003fc00000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020b1d000 CR3: 000000003bde9000 CR4: 00000000000006f0
Call Trace:
 lock_acquire+0x2a1/0x630 kernel/locking/lockdep.c:3753
 __raw_spin_lock include/linux/spinlock_api_smp.h:144 [inline]
 _raw_spin_lock+0x33/0x50 kernel/locking/spinlock.c:151
 spin_lock include/linux/spinlock.h:302 [inline]
 list_lru_add+0x10b/0x340 mm/list_lru.c:115
 d_lru_add fs/dcache.c:366 [inline]
 dentry_lru_add fs/dcache.c:421 [inline]
 dput.part.27+0x659/0x7c0 fs/dcache.c:784
 dput+0x1f/0x30 fs/dcache.c:753
 path_put+0x31/0x70 fs/namei.c:500
 unix_bind+0x424/0xea0 net/unix/af_unix.c:1072
 SYSC_bind+0x20e/0x4a0 net/socket.c:1413
 SyS_bind+0x24/0x30 net/socket.c:1399
 entry_SYSCALL_64_fastpath+0x1f/0xc2
RIP: 0033:0x4454b9
RSP: 002b:00007f4f8eb5cb58 EFLAGS: 00000292 ORIG_RAX: 0000000000000031
RAX: ffffffffffffffda RBX: 000000000000001d RCX: 00000000004454b9
RDX: 0000000000000008 RSI: 000000002002cff8 RDI: 000000000000001d
RBP: 00000000006dd230 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000292 R12: 0000000000700000
R13: 00007f4f8f2de9d0 R14: 00007f4f8f2dfc40 R15: 0000000000000000
Code: e9 03 f3 48 ab 48 81 c4 10 05 00 00 44 89 e8 5b 41 5c 41 5d 41
5e 41 5f 5d c3 4c 89 d2 48 b8 00 00 00 00 00 fc ff df 48 c1 ea 03 <80>
3c 02 00 0f 85 9e 26 00 00 49 81 3a e0 be 6b 85 41 bf 00 00
RIP: __lock_acquire+0xb3a/0x3430 kernel/locking/lockdep.c:3224 RSP:
ffff88003a9a7218
---[ end trace 78951d69744a2fe1 ]---
Kernel panic - not syncing: Fatal exception
Dumping ftrace buffer:
   (ftrace buffer empty)
Kernel Offset: disabled


and:


BUG: KASAN: use-after-free in list_lru_add+0x2fd/0x340
mm/list_lru.c:112 at addr ffff88006b301340
Read of size 8 by task syz-executor0/7116
CPU: 2 PID: 7116 Comm: syz-executor0 Not tainted 4.10.0-rc4+ #177
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:15 [inline]
 dump_stack+0x2ee/0x3ef lib/dump_stack.c:51
 kasan_object_err+0x1c/0x70 mm/kasan/report.c:165
 print_address_description mm/kasan/report.c:203 [inline]
 kasan_report_error mm/kasan/report.c:287 [inline]
 kasan_report+0x1b6/0x460 mm/kasan/report.c:307
 __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:333
 list_lru_add+0x2fd/0x340 mm/list_lru.c:112
 d_lru_add fs/dcache.c:366 [inline]
 dentry_lru_add fs/dcache.c:421 [inline]
 dput.part.27+0x659/0x7c0 fs/dcache.c:784
 dput+0x1f/0x30 fs/dcache.c:753
 path_put+0x31/0x70 fs/namei.c:500
 unix_bind+0x424/0xea0 net/unix/af_unix.c:1072
 SYSC_bind+0x20e/0x4a0 net/socket.c:1413
 SyS_bind+0x24/0x30 net/socket.c:1399
 entry_SYSCALL_64_fastpath+0x1f/0xc2
RIP: 0033:0x4454b9
RSP: 002b:00007f1b034ebb58 EFLAGS: 00000292 ORIG_RAX: 0000000000000031
RAX: ffffffffffffffda RBX: 0000000000000016 RCX: 00000000004454b9
RDX: 0000000000000008 RSI: 000000002002eff8 RDI: 0000000000000016
RBP: 00000000006dd230 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000292 R12: 0000000000700000
R13: 00007f1b03c6d458 R14: 00007f1b03c6e5e8 R15: 0000000000000000
Object at ffff88006b301300, in cache vm_area_struct size: 192
Allocated:
PID = 1391

[<ffffffff812b2686>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57

[<ffffffff81a0e713>] save_stack+0x43/0xd0 mm/kasan/kasan.c:502

[<ffffffff81a0e9da>] set_track mm/kasan/kasan.c:514 [inline]
[<ffffffff81a0e9da>] kasan_kmalloc+0xaa/0xd0 mm/kasan/kasan.c:605

[<ffffffff81a0efd2>] kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:544

[<ffffffff81a0a5e2>] kmem_cache_alloc+0x102/0x680 mm/slab.c:3563

[<ffffffff8144093b>] dup_mmap kernel/fork.c:609 [inline]
[<ffffffff8144093b>] dup_mm kernel/fork.c:1145 [inline]
[<ffffffff8144093b>] copy_mm kernel/fork.c:1199 [inline]
[<ffffffff8144093b>] copy_process.part.42+0x503b/0x5fd0 kernel/fork.c:1669

[<ffffffff81441e10>] copy_process kernel/fork.c:1494 [inline]
[<ffffffff81441e10>] _do_fork+0x200/0xff0 kernel/fork.c:1950

[<ffffffff81442cd7>] SYSC_clone kernel/fork.c:2060 [inline]
[<ffffffff81442cd7>] SyS_clone+0x37/0x50 kernel/fork.c:2054

[<ffffffff81009798>] do_syscall_64+0x2e8/0x930 arch/x86/entry/common.c:280

[<ffffffff841cadc9>] return_from_SYSCALL_64+0x0/0x7a
Freed:
PID = 5275

[<ffffffff812b2686>] save_stack_trace+0x16/0x20 arch/x86/kernel/stacktrace.c:57

[<ffffffff81a0e713>] save_stack+0x43/0xd0 mm/kasan/kasan.c:502

[<ffffffff81a0f04f>] set_track mm/kasan/kasan.c:514 [inline]
[<ffffffff81a0f04f>] kasan_slab_free+0x6f/0xb0 mm/kasan/kasan.c:578

[<ffffffff81a0c3b1>] __cache_free mm/slab.c:3505 [inline]
[<ffffffff81a0c3b1>] kmem_cache_free+0x71/0x240 mm/slab.c:3765

[<ffffffff81976992>] remove_vma+0x162/0x1b0 mm/mmap.c:175

[<ffffffff8197f72f>] exit_mmap+0x2ef/0x490 mm/mmap.c:2952

[<ffffffff814390bb>] __mmput kernel/fork.c:873 [inline]
[<ffffffff814390bb>] mmput+0x22b/0x6e0 kernel/fork.c:895

[<ffffffff81453a3f>] exit_mm kernel/exit.c:521 [inline]
[<ffffffff81453a3f>] do_exit+0x9cf/0x28a0 kernel/exit.c:826

[<ffffffff8145a369>] do_group_exit+0x149/0x420 kernel/exit.c:943

[<ffffffff81489630>] get_signal+0x7e0/0x1820 kernel/signal.c:2313

[<ffffffff8127ca92>] do_signal+0xd2/0x2190 arch/x86/kernel/signal.c:807

[<ffffffff81007900>] exit_to_usermode_loop+0x200/0x2a0
arch/x86/entry/common.c:156

[<ffffffff81009413>] prepare_exit_to_usermode
arch/x86/entry/common.c:190 [inline]
[<ffffffff81009413>] syscall_return_slowpath+0x4d3/0x570
arch/x86/entry/common.c:259

[<ffffffff841cada2>] entry_SYSCALL_64_fastpath+0xc0/0xc2
Memory state around the buggy address:
 ffff88006b301200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff88006b301280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff88006b301300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                           ^
 ffff88006b301380: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
 ffff88006b301400: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

^ permalink raw reply

* RE: [PATCH v2 1/2] xen-netback: fix memory leaks on XenBus disconnect
From: Paul Durrant @ 2017-01-18  9:27 UTC (permalink / raw)
  To: Igor Druzhinin, Wei Liu
  Cc: xen-devel@lists.xenproject.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, Igor Druzhinin
In-Reply-To: <1484686178-76959-2-git-send-email-igor.druzhinin@citrix.com>

> -----Original Message-----
> From: Igor Druzhinin [mailto:igor.druzhinin@citrix.com]
> Sent: 17 January 2017 20:50
> To: Wei Liu <wei.liu2@citrix.com>
> Cc: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Igor Druzhinin
> <igor.druzhinin@citrix.com>
> Subject: [PATCH v2 1/2] xen-netback: fix memory leaks on XenBus
> disconnect
> 
> Eliminate memory leaks introduced several years ago by cleaning the
> queue resources which are allocated on XenBus connection event. Namely,
> queue
> structure array and pages used for IO rings.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Paul Durrant <paul.durrant@citrix.com>

> ---
>  drivers/net/xen-netback/xenbus.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-
> netback/xenbus.c
> index 6c57b02..3e99071 100644
> --- a/drivers/net/xen-netback/xenbus.c
> +++ b/drivers/net/xen-netback/xenbus.c
> @@ -493,11 +493,20 @@ static int backend_create_xenvif(struct
> backend_info *be)
>  static void backend_disconnect(struct backend_info *be)
>  {
>  	if (be->vif) {
> +		unsigned int queue_index;
> +
>  		xen_unregister_watchers(be->vif);
>  #ifdef CONFIG_DEBUG_FS
>  		xenvif_debugfs_delif(be->vif);
>  #endif /* CONFIG_DEBUG_FS */
>  		xenvif_disconnect_data(be->vif);
> +		for (queue_index = 0; queue_index < be->vif-
> >num_queues; ++queue_index)
> +			xenvif_deinit_queue(&be->vif-
> >queues[queue_index]);
> +
> +		vfree(be->vif->queues);
> +		be->vif->num_queues = 0;
> +		be->vif->queues = NULL;
> +
>  		xenvif_disconnect_ctrl(be->vif);
>  	}
>  }
> @@ -1026,6 +1035,8 @@ static void connect(struct backend_info *be)
>  err:
>  	if (be->vif->num_queues > 0)
>  		xenvif_disconnect_data(be->vif); /* Clean up existing
> queues */
> +	for (queue_index = 0; queue_index < be->vif->num_queues;
> ++queue_index)
> +		xenvif_deinit_queue(&be->vif->queues[queue_index]);
>  	vfree(be->vif->queues);
>  	be->vif->queues = NULL;
>  	be->vif->num_queues = 0;
> --
> 1.8.3.1

^ permalink raw reply

* Re: [PATCH net-next] mlx4: support __GFP_MEMALLOC for rx
From: Konstantin Khlebnikov @ 2017-01-18  9:31 UTC (permalink / raw)
  To: Eric Dumazet, David Miller; +Cc: netdev, Tariq Toukan, linux-mm@kvack.org
In-Reply-To: <1484712850.13165.86.camel@edumazet-glaptop3.roam.corp.google.com>

On 18.01.2017 07:14, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> Commit 04aeb56a1732 ("net/mlx4_en: allocate non 0-order pages for RX
> ring with __GFP_NOMEMALLOC") added code that appears to be not needed at
> that time, since mlx4 never used __GFP_MEMALLOC allocations anyway.
>
> As using memory reserves is a must in some situations (swap over NFS or
> iSCSI), this patch adds this flag.

AFAIK __GFP_MEMALLOC is used for TX, not for RX: for allocations which are required by memory reclaimer to free some pages.

Allocation RX buffers with __GFP_MEMALLOC is a straight way to depleting all reserves by flood from network.

>
> Note that this driver does not reuse pages (yet) so we do not have to
> add anything else.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
> Cc: Tariq Toukan <tariqt@mellanox.com>
> ---
>  drivers/net/ethernet/mellanox/mlx4/en_rx.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
> index eac527e25ec902c2a586e9952272b9e8e599e2c8..e362f99334d03c0df4d88320977670015870dd9c 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
> @@ -706,7 +706,8 @@ static bool mlx4_en_refill_rx_buffers(struct mlx4_en_priv *priv,
>  	do {
>  		if (mlx4_en_prepare_rx_desc(priv, ring,
>  					    ring->prod & ring->size_mask,
> -					    GFP_ATOMIC | __GFP_COLD))
> +					    GFP_ATOMIC | __GFP_COLD |
> +					    __GFP_MEMALLOC))
>  			break;
>  		ring->prod++;
>  	} while (--missing);
>
>


-- 
Konstantin

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* [PATCH] can: ti_hecc: add missing prepare and unprepare of the clock
From: yegorslists @ 2017-01-18  9:43 UTC (permalink / raw)
  To: linux-can; +Cc: netdev, mkl, wg, Yegor Yefremov

From: Yegor Yefremov <yegorslists@googlemail.com>

In order to make the driver work with the common clock framework, this
patch converts the clk_enable()/clk_disable() to
clk_prepare_enable()/clk_disable_unprepare().

Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
---
 drivers/net/can/ti_hecc.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 680d1ff..0448cb5 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -948,7 +948,8 @@ static int ti_hecc_probe(struct platform_device *pdev)
 	netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
 		HECC_DEF_NAPI_WEIGHT);
 
-	clk_enable(priv->clk);
+	clk_prepare_enable(priv->clk);
+
 	err = register_candev(ndev);
 	if (err) {
 		dev_err(&pdev->dev, "register_candev() failed\n");
@@ -981,7 +982,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
 	struct ti_hecc_priv *priv = netdev_priv(ndev);
 
 	unregister_candev(ndev);
-	clk_disable(priv->clk);
+	clk_disable_unprepare(priv->clk);
 	clk_put(priv->clk);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	iounmap(priv->base);
@@ -1006,7 +1007,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
 	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
 	priv->can.state = CAN_STATE_SLEEPING;
 
-	clk_disable(priv->clk);
+	clk_disable_unprepare(priv->clk);
 
 	return 0;
 }
@@ -1016,7 +1017,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
 	struct net_device *dev = platform_get_drvdata(pdev);
 	struct ti_hecc_priv *priv = netdev_priv(dev);
 
-	clk_enable(priv->clk);
+	clk_prepare_enable(priv->clk);
 
 	hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH v2 1/2] xen-netback: fix memory leaks on XenBus disconnect
From: Wei Liu @ 2017-01-18  9:45 UTC (permalink / raw)
  To: Igor Druzhinin; +Cc: xen-devel, Paul.Durrant, wei.liu2, linux-kernel, netdev
In-Reply-To: <1484686178-76959-2-git-send-email-igor.druzhinin@citrix.com>

On Tue, Jan 17, 2017 at 08:49:37PM +0000, Igor Druzhinin wrote:
> Eliminate memory leaks introduced several years ago by cleaning the
> queue resources which are allocated on XenBus connection event. Namely, queue
> structure array and pages used for IO rings.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply

* Re: [PATCH v2 2/2] xen-netback: protect resource cleaning on XenBus disconnect
From: Wei Liu @ 2017-01-18  9:45 UTC (permalink / raw)
  To: Igor Druzhinin; +Cc: xen-devel, Paul.Durrant, wei.liu2, linux-kernel, netdev
In-Reply-To: <1484686178-76959-3-git-send-email-igor.druzhinin@citrix.com>

On Tue, Jan 17, 2017 at 08:49:38PM +0000, Igor Druzhinin wrote:
> vif->lock is used to protect statistics gathering agents from using the
> queue structure during cleaning.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Acked-by: Wei Liu <wei.liu2@citrix.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply

* Re: [PATCH v2 2/2] xen-netback: protect resource cleaning on XenBus disconnect
From: Paul Durrant @ 2017-01-18  9:46 UTC (permalink / raw)
  To: Igor Druzhinin, Wei Liu
  Cc: xen-devel@lists.xenproject.org, Igor Druzhinin,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org
In-Reply-To: <1484686178-76959-3-git-send-email-igor.druzhinin@citrix.com>

> -----Original Message-----
> From: Igor Druzhinin [mailto:igor.druzhinin@citrix.com]
> Sent: 17 January 2017 20:50
> To: Wei Liu <wei.liu2@citrix.com>
> Cc: Paul Durrant <Paul.Durrant@citrix.com>; xen-devel@lists.xenproject.org;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Igor Druzhinin
> <igor.druzhinin@citrix.com>
> Subject: [PATCH v2 2/2] xen-netback: protect resource cleaning on XenBus
> disconnect
> 
> vif->lock is used to protect statistics gathering agents from using the
> queue structure during cleaning.
> 
> Signed-off-by: Igor Druzhinin <igor.druzhinin@citrix.com>

Reviewed-by: Paul Durrant <paul.durrant@citrix.com>

> ---
>  drivers/net/xen-netback/interface.c | 6 ++++--
>  drivers/net/xen-netback/xenbus.c    | 2 ++
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-
> netback/interface.c
> index 41c69b3..c48252a 100644
> --- a/drivers/net/xen-netback/interface.c
> +++ b/drivers/net/xen-netback/interface.c
> @@ -230,18 +230,18 @@ static struct net_device_stats
> *xenvif_get_stats(struct net_device *dev)
>  {
>  	struct xenvif *vif = netdev_priv(dev);
>  	struct xenvif_queue *queue = NULL;
> -	unsigned int num_queues = vif->num_queues;
>  	unsigned long rx_bytes = 0;
>  	unsigned long rx_packets = 0;
>  	unsigned long tx_bytes = 0;
>  	unsigned long tx_packets = 0;
>  	unsigned int index;
> 
> +	spin_lock(&vif->lock);
>  	if (vif->queues == NULL)
>  		goto out;
> 
>  	/* Aggregate tx and rx stats from each queue */
> -	for (index = 0; index < num_queues; ++index) {
> +	for (index = 0; index < vif->num_queues; ++index) {
>  		queue = &vif->queues[index];
>  		rx_bytes += queue->stats.rx_bytes;
>  		rx_packets += queue->stats.rx_packets;
> @@ -250,6 +250,8 @@ static struct net_device_stats
> *xenvif_get_stats(struct net_device *dev)
>  	}
> 
>  out:
> +	spin_unlock(&vif->lock);
> +
>  	vif->dev->stats.rx_bytes = rx_bytes;
>  	vif->dev->stats.rx_packets = rx_packets;
>  	vif->dev->stats.tx_bytes = tx_bytes;
> diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-
> netback/xenbus.c
> index 3e99071..d82cd71 100644
> --- a/drivers/net/xen-netback/xenbus.c
> +++ b/drivers/net/xen-netback/xenbus.c
> @@ -503,9 +503,11 @@ static void backend_disconnect(struct backend_info
> *be)
>  		for (queue_index = 0; queue_index < be->vif-
> >num_queues; ++queue_index)
>  			xenvif_deinit_queue(&be->vif-
> >queues[queue_index]);
> 
> +		spin_lock(&be->vif->lock);
>  		vfree(be->vif->queues);
>  		be->vif->num_queues = 0;
>  		be->vif->queues = NULL;
> +		spin_unlock(&be->vif->lock);
> 
>  		xenvif_disconnect_ctrl(be->vif);
>  	}
> --
> 1.8.3.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply

* Re: [PATCH for bnxt_re V4 09/21] RDMA/bnxt_re: Support for GID related verbs
From: Leon Romanovsky @ 2017-01-18  9:50 UTC (permalink / raw)
  To: Selvin Xavier
  Cc: dledford, linux-rdma, netdev, michael.chan, Eddie Wai,
	Devesh Sharma, Somnath Kotur, Sriharsha Basavapatna
In-Reply-To: <1482320530-5344-10-git-send-email-selvin.xavier@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 1694 bytes --]

On Wed, Dec 21, 2016 at 03:41:58AM -0800, Selvin Xavier wrote:
> Implements add GID, del GID,  get_netdev and pkey related verbs.
>
> v3: Fixes some sparse warning related to endianness check. Removes
>     macros which are just wrapper for standard defines.
>
> Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
> Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> ---
>  drivers/infiniband/hw/bnxt_re/ib_verbs.c  | 123 +++++++++++++++++
>  drivers/infiniband/hw/bnxt_re/ib_verbs.h  |  18 +++
>  drivers/infiniband/hw/bnxt_re/main.c      |   7 +
>  drivers/infiniband/hw/bnxt_re/qplib_res.c |   5 +
>  drivers/infiniband/hw/bnxt_re/qplib_res.h |   3 +
>  drivers/infiniband/hw/bnxt_re/qplib_sp.c  | 218 ++++++++++++++++++++++++++++++
>  drivers/infiniband/hw/bnxt_re/qplib_sp.h  |  11 ++
>  7 files changed, 385 insertions(+)
>

<snip>

> +
> +int bnxt_qplib_del_sgid(struct bnxt_qplib_sgid_tbl *sgid_tbl,
> +			struct bnxt_qplib_gid *gid, bool update)
> +{
> +	struct bnxt_qplib_res *res = to_bnxt_qplib(sgid_tbl,
> +						   struct bnxt_qplib_res,
> +						   sgid_tbl);
> +	struct bnxt_qplib_rcfw *rcfw = res->rcfw;
> +	int index;
> +
> +	if (!sgid_tbl) {
> +		dev_err(&res->pdev->dev, "QPLIB: SGID table not allocated");
> +		return -EINVAL;
> +	}
> +	/* Do we need a sgid_lock here? */

It is better to answer on this question before acceptance.

> +	if (!sgid_tbl->active) {
> +		dev_err(&res->pdev->dev,
> +			"QPLIB: SGID table has no active entries");
> +		return -ENOMEM;
> +	}

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* RE: Kernel 4.6.7-rt14 kernel workqueue lockup - rtnl deadlock plus syscall endless loop
From: Elad Nachman @ 2017-01-18  9:57 UTC (permalink / raw)
  To: David Miller; +Cc: netdev@vger.kernel.org
In-Reply-To: <20170117.140552.539738967862859087.davem@davemloft.net>

OK, how about reflecting the state of the rtnl lock to user space via the /proc file system?

This way I can test it before using sysctl on the relevant proc files to avoid live-lock.

Thanks,

Elad.

-----Original Message-----
From: David Miller [mailto:davem@davemloft.net]
Sent: יום ג 17 ינואר 2017 21:06
To: Elad Nachman <EladN@gilat.com>
Cc: netdev@vger.kernel.org
Subject: Re: Kernel 4.6.7-rt14 kernel workqueue lockup - rtnl deadlock plus syscall endless loop

From: Elad Nachman <EladN@gilat.com>
Date: Tue, 17 Jan 2017 18:15:19 +0000

> Any thought about limiting the amount of busy polling?  Say if more
> than X polls are done within a jiffy, then at least for preemptable
> kernels you can sleep for a jiffy inside the syscall to yield the
> CPU for a while?

We cannot yield there, because we must return immediately from this
context in order to drop the sysctl locks and references.
IMPORTANT - This email and any attachments is intended for the above named addressee(s), and may contain information which is confidential or privileged. If you are not the intended recipient, please inform the sender immediately and delete this email: you should not copy or use this e-mail for any purpose nor disclose its contents to any person.

^ permalink raw reply

* Re: [PATCH] can: ti_hecc: add missing prepare and unprepare of the clock
From: Marc Kleine-Budde @ 2017-01-18 10:01 UTC (permalink / raw)
  To: yegorslists, linux-can; +Cc: netdev, wg
In-Reply-To: <1484732616-4461-1-git-send-email-yegorslists@googlemail.com>


[-- Attachment #1.1: Type: text/plain, Size: 2352 bytes --]

On 01/18/2017 10:43 AM, yegorslists@googlemail.com wrote:
> From: Yegor Yefremov <yegorslists@googlemail.com>
> 
> In order to make the driver work with the common clock framework, this
> patch converts the clk_enable()/clk_disable() to
> clk_prepare_enable()/clk_disable_unprepare().
> 

Can you add the missing error checking for the prepare_enable call?

Marc

> Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
> ---
>  drivers/net/can/ti_hecc.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
> index 680d1ff..0448cb5 100644
> --- a/drivers/net/can/ti_hecc.c
> +++ b/drivers/net/can/ti_hecc.c
> @@ -948,7 +948,8 @@ static int ti_hecc_probe(struct platform_device *pdev)
>  	netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
>  		HECC_DEF_NAPI_WEIGHT);
>  
> -	clk_enable(priv->clk);
> +	clk_prepare_enable(priv->clk);
> +
>  	err = register_candev(ndev);
>  	if (err) {
>  		dev_err(&pdev->dev, "register_candev() failed\n");
> @@ -981,7 +982,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
>  	struct ti_hecc_priv *priv = netdev_priv(ndev);
>  
>  	unregister_candev(ndev);
> -	clk_disable(priv->clk);
> +	clk_disable_unprepare(priv->clk);
>  	clk_put(priv->clk);
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	iounmap(priv->base);
> @@ -1006,7 +1007,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
>  	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
>  	priv->can.state = CAN_STATE_SLEEPING;
>  
> -	clk_disable(priv->clk);
> +	clk_disable_unprepare(priv->clk);
>  
>  	return 0;
>  }
> @@ -1016,7 +1017,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
>  	struct net_device *dev = platform_get_drvdata(pdev);
>  	struct ti_hecc_priv *priv = netdev_priv(dev);
>  
> -	clk_enable(priv->clk);
> +	clk_prepare_enable(priv->clk);
>  
>  	hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
>  	priv->can.state = CAN_STATE_ERROR_ACTIVE;
> 


-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH for bnxt_re V4 03/21] RDMA/bnxt_re: register with the NIC driver
From: Leon Romanovsky @ 2017-01-18 10:11 UTC (permalink / raw)
  To: Selvin Xavier
  Cc: dledford, linux-rdma, netdev, michael.chan, Eddie Wai,
	Devesh Sharma, Somnath Kotur, Sriharsha Basavapatna
In-Reply-To: <1482320530-5344-4-git-send-email-selvin.xavier@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 15667 bytes --]

On Wed, Dec 21, 2016 at 03:41:52AM -0800, Selvin Xavier wrote:
> This patch handles the registration with the bnxt_en driver.
> The bnxt_re driver first registers with netdev notifier chain and upon
> receiving the NETDEV_REGISTER event, it registers with bnxt_en driver.
>
> 	1. bnxt_en's ulp_probe function returns a structure that contains
> 	   information 	about the device and additional entry points.
> 	2. bnxt_en driver returns 'struct bnxt_eth_dev' that contains set
> 	   of operation  vectors that bnxt_re driver invokes later.
> 	3. bnxt_request_msix() allows the bnxt_re driver to specify the
> 	   number of MSI-X vectors that are needed.
> 	4. bnxt_send_fw_msg () is used to send messages to the FW
> 	5. bnxt_register_async_events() is used to register for async
> 	   event callbacks.
>
> v2: Remove some sparse warning. Also, remove some unused code from unreg
>     path.
> v3: Removed condition checks for rdev reported during static code analysis.
>     Check the return value of try_module_get while getting bnxt_en
>     reference.
>
> Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
> Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
> Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
> Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
> Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
> ---
>  drivers/infiniband/hw/bnxt_re/bnxt_re.h |  51 ++++
>  drivers/infiniband/hw/bnxt_re/main.c    | 448 ++++++++++++++++++++++++++++++++
>  2 files changed, 499 insertions(+)
>
> diff --git a/drivers/infiniband/hw/bnxt_re/bnxt_re.h b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> index f9b8542..8b73e3d 100644
> --- a/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> +++ b/drivers/infiniband/hw/bnxt_re/bnxt_re.h
> @@ -42,5 +42,56 @@
>  #define ROCE_DRV_MODULE_NAME		"bnxt_re"
>  #define ROCE_DRV_MODULE_VERSION		"1.0.0"
>
> +#define BNXT_RE_REF_WAIT_COUNT		10
>  #define BNXT_RE_DESC	"Broadcom NetXtreme-C/E RoCE Driver"
> +
> +struct bnxt_re_work {
> +	struct work_struct	work;
> +	unsigned long		event;
> +	struct bnxt_re_dev      *rdev;
> +	struct net_device	*vlan_dev;
> +};
> +
> +#define BNXT_RE_MIN_MSIX		2
> +#define BNXT_RE_MAX_MSIX		16
> +struct bnxt_re_dev {
> +	struct ib_device		ibdev;
> +	struct list_head		list;
> +	atomic_t			ref_count;
> +	unsigned long			flags;
> +#define BNXT_RE_FLAG_NETDEV_REGISTERED	0
> +#define BNXT_RE_FLAG_IBDEV_REGISTERED	1
> +#define BNXT_RE_FLAG_GOT_MSIX		2
> +#define BNXT_RE_FLAG_RCFW_CHANNEL_EN	8
> +#define BNXT_RE_FLAG_QOS_WORK_REG	16
> +	struct net_device		*netdev;
> +	unsigned int			version, major, minor;
> +	struct bnxt_en_dev		*en_dev;
> +	struct bnxt_msix_entry		msix_entries[BNXT_RE_MAX_MSIX];
> +	int				num_msix;
> +
> +	int				id;
> +
> +	atomic_t			qp_count;
> +	struct mutex			qp_lock;	/* protect qp list */
> +	struct list_head		qp_list;
> +
> +	atomic_t			cq_count;
> +	atomic_t			srq_count;
> +	atomic_t			mr_count;
> +	atomic_t			mw_count;
> +	/* Max of 2 lossless traffic class supported per port */
> +	u16				cosq[2];
> +};
> +
> +#define to_bnxt_re_dev(ptr, member)	\
> +	container_of((ptr), struct bnxt_re_dev, member)
> +
> +static inline struct device *rdev_to_dev(struct bnxt_re_dev *rdev)
> +{
> +	if (rdev)
> +		return  &rdev->ibdev.dev;
> +	return NULL;
> +}
> +
>  #endif
> diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c
> index 6c22d51..71d7501 100644
> --- a/drivers/infiniband/hw/bnxt_re/main.c
> +++ b/drivers/infiniband/hw/bnxt_re/main.c
> @@ -38,10 +38,24 @@
>
>  #include <linux/module.h>
>  #include <linux/netdevice.h>
> +#include <linux/ethtool.h>
>  #include <linux/mutex.h>
>  #include <linux/list.h>
>  #include <linux/rculist.h>
> +#include <linux/spinlock.h>
> +#include <linux/pci.h>
> +#include <net/ipv6.h>
> +#include <net/addrconf.h>
> +
> +#include <rdma/ib_verbs.h>
> +#include <rdma/ib_user_verbs.h>
> +#include <rdma/ib_umem.h>
> +#include <rdma/ib_addr.h>
> +
> +#include "bnxt_ulp.h"
> +#include "roce_hsi.h"
>  #include "bnxt_re.h"
> +#include "bnxt.h"
>  static char version[] =
>  		BNXT_RE_DESC " v" ROCE_DRV_MODULE_VERSION "\n";
>
> @@ -55,6 +69,384 @@ static struct list_head bnxt_re_dev_list = LIST_HEAD_INIT(bnxt_re_dev_list);
>  /* Mutex to protect the list of bnxt_re devices added */
>  static DEFINE_MUTEX(bnxt_re_dev_lock);
>  static struct workqueue_struct *bnxt_re_wq;
> +
> +/* for handling bnxt_en callbacks later */
> +static void bnxt_re_stop(void *p)
> +{
> +}
> +
> +static void bnxt_re_start(void *p)
> +{
> +}
> +
> +static void bnxt_re_sriov_config(void *p, int num_vfs)
> +{
> +}
> +
> +static struct bnxt_ulp_ops bnxt_re_ulp_ops = {
> +	.ulp_async_notifier = NULL,
> +	.ulp_stop = bnxt_re_stop,
> +	.ulp_start = bnxt_re_start,
> +	.ulp_sriov_config = bnxt_re_sriov_config
> +};
> +
> +/* The rdev ref_count is to protect immature removal of the device */
> +static inline void bnxt_re_hold(struct bnxt_re_dev *rdev)
> +{
> +	atomic_inc(&rdev->ref_count);
> +}
> +
> +static inline void bnxt_re_put(struct bnxt_re_dev *rdev)
> +{
> +	atomic_dec(&rdev->ref_count);
> +}
> +
> +/* RoCE -> Net driver */
> +
> +/* Driver registration routines used to let the networking driver (bnxt_en)
> + * to know that the RoCE driver is now installed
> + */
> +static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev, bool lock_wait)
> +{
> +	struct bnxt_en_dev *en_dev;
> +	int rc;
> +
> +	if (!rdev)
> +		return -EINVAL;
> +
> +	en_dev = rdev->en_dev;
> +	/* Acquire rtnl lock if it is not invokded from netdev event */
> +	if (lock_wait)
> +		rtnl_lock();
> +
> +	rc = en_dev->en_ops->bnxt_unregister_device(rdev->en_dev,
> +						    BNXT_ROCE_ULP);
> +	if (lock_wait)
> +		rtnl_unlock();
> +	return rc;
> +}
> +
> +static int bnxt_re_register_netdev(struct bnxt_re_dev *rdev)
> +{
> +	struct bnxt_en_dev *en_dev;
> +	int rc = 0;
> +
> +	if (!rdev)
> +		return -EINVAL;
> +
> +	en_dev = rdev->en_dev;
> +
> +	rtnl_lock();
> +	rc = en_dev->en_ops->bnxt_register_device(en_dev, BNXT_ROCE_ULP,
> +						  &bnxt_re_ulp_ops, rdev);
> +	rtnl_unlock();
> +	return rc;
> +}
> +
> +static int bnxt_re_free_msix(struct bnxt_re_dev *rdev, bool lock_wait)
> +{
> +	struct bnxt_en_dev *en_dev;
> +	int rc;
> +
> +	if (!rdev)
> +		return -EINVAL;
> +
> +	en_dev = rdev->en_dev;
> +
> +	if (lock_wait)
> +		rtnl_lock();
> +
> +	rc = en_dev->en_ops->bnxt_free_msix(rdev->en_dev, BNXT_ROCE_ULP);
> +
> +	if (lock_wait)
> +		rtnl_unlock();
> +	return rc;
> +}
> +
> +static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
> +{
> +	int rc = 0, num_msix_want = BNXT_RE_MIN_MSIX, num_msix_got;
> +	struct bnxt_en_dev *en_dev;
> +
> +	if (!rdev)
> +		return -EINVAL;
> +
> +	en_dev = rdev->en_dev;
> +
> +	rtnl_lock();
> +	num_msix_got = en_dev->en_ops->bnxt_request_msix(en_dev, BNXT_ROCE_ULP,
> +							 rdev->msix_entries,
> +							 num_msix_want);
> +	if (num_msix_got < BNXT_RE_MIN_MSIX) {
> +		rc = -EINVAL;
> +		goto done;
> +	}
> +	if (num_msix_got != num_msix_want) {
> +		dev_warn(rdev_to_dev(rdev),
> +			 "Requested %d MSI-X vectors, got %d\n",
> +			 num_msix_want, num_msix_got);
> +	}
> +	rdev->num_msix = num_msix_got;
> +done:
> +	rtnl_unlock();
> +	return rc;
> +}
> +
> +/* Device */
> +
> +static bool is_bnxt_re_dev(struct net_device *netdev)
> +{
> +	struct ethtool_drvinfo drvinfo;
> +
> +	if (netdev->ethtool_ops && netdev->ethtool_ops->get_drvinfo) {
> +		memset(&drvinfo, 0, sizeof(drvinfo));
> +		netdev->ethtool_ops->get_drvinfo(netdev, &drvinfo);
> +
> +		if (strcmp(drvinfo.driver, "bnxt_en"))
> +			return false;
> +		return true;
> +	}
> +	return false;
> +}
> +
> +static struct bnxt_re_dev *bnxt_re_from_netdev(struct net_device *netdev)
> +{
> +	struct bnxt_re_dev *rdev;
> +
> +	rcu_read_lock();
> +	list_for_each_entry_rcu(rdev, &bnxt_re_dev_list, list) {
> +		if (rdev->netdev == netdev) {
> +			rcu_read_unlock();
> +			return rdev;
> +		}
> +	}
> +	rcu_read_unlock();
> +	return NULL;
> +}
> +
> +static void bnxt_re_dev_unprobe(struct net_device *netdev,
> +				struct bnxt_en_dev *en_dev)
> +{
> +	dev_put(netdev);
> +	module_put(en_dev->pdev->driver->driver.owner);
> +}
> +
> +static struct bnxt_en_dev *bnxt_re_dev_probe(struct net_device *netdev)
> +{
> +	struct bnxt *bp = netdev_priv(netdev);
> +	struct bnxt_en_dev *en_dev;
> +	struct pci_dev *pdev;
> +
> +	/* Call bnxt_en's RoCE probe via indirect API */
> +	if (!bp->ulp_probe)
> +		return ERR_PTR(-EINVAL);
> +
> +	en_dev = bp->ulp_probe(netdev);
> +	if (IS_ERR(en_dev))
> +		return en_dev;
> +
> +	pdev = en_dev->pdev;
> +	if (!pdev)
> +		return ERR_PTR(-EINVAL);
> +
> +	/* Bump net device reference count */
> +	if (!try_module_get(pdev->driver->driver.owner))
> +		return ERR_PTR(-ENODEV);
> +
> +	dev_hold(netdev);
> +
> +	return en_dev;
> +}
> +
> +static void bnxt_re_dev_remove(struct bnxt_re_dev *rdev)
> +{
> +	int i = BNXT_RE_REF_WAIT_COUNT;
> +
> +	/* Wait for rdev refcount to come down */
> +	while ((atomic_read(&rdev->ref_count) > 1) && i--)
> +		msleep(100);
> +
> +	if (atomic_read(&rdev->ref_count) > 1)
> +		dev_err(rdev_to_dev(rdev),
> +			"Failed waiting for ref count to deplete %d",
> +			atomic_read(&rdev->ref_count));
> +
> +	atomic_set(&rdev->ref_count, 0);
> +	dev_put(rdev->netdev);
> +	rdev->netdev = NULL;
> +
> +	mutex_lock(&bnxt_re_dev_lock);
> +	list_del_rcu(&rdev->list);
> +	mutex_unlock(&bnxt_re_dev_lock);
> +
> +	synchronize_rcu();
> +	flush_workqueue(bnxt_re_wq);
> +
> +	ib_dealloc_device(&rdev->ibdev);
> +	/* rdev is gone */
> +}
> +
> +static struct bnxt_re_dev *bnxt_re_dev_add(struct net_device *netdev,
> +					   struct bnxt_en_dev *en_dev)
> +{
> +	struct bnxt_re_dev *rdev;
> +
> +	/* Allocate bnxt_re_dev instance here */
> +	rdev = (struct bnxt_re_dev *)ib_alloc_device(sizeof(*rdev));
> +	if (!rdev) {
> +		dev_err(NULL, "%s: bnxt_re_dev allocation failure!",
> +			ROCE_DRV_MODULE_NAME);
> +		return NULL;
> +	}
> +	/* Default values */
> +	atomic_set(&rdev->ref_count, 0);
> +	rdev->netdev = netdev;
> +	dev_hold(rdev->netdev);
> +	rdev->en_dev = en_dev;
> +	rdev->id = rdev->en_dev->pdev->devfn;
> +	INIT_LIST_HEAD(&rdev->qp_list);
> +	mutex_init(&rdev->qp_lock);
> +	atomic_set(&rdev->qp_count, 0);
> +	atomic_set(&rdev->cq_count, 0);
> +	atomic_set(&rdev->srq_count, 0);
> +	atomic_set(&rdev->mr_count, 0);
> +	atomic_set(&rdev->mw_count, 0);
> +	rdev->cosq[0] = 0xFFFF;
> +	rdev->cosq[1] = 0xFFFF;
> +
> +	mutex_lock(&bnxt_re_dev_lock);
> +	list_add_tail_rcu(&rdev->list, &bnxt_re_dev_list);
> +	mutex_unlock(&bnxt_re_dev_lock);
> +	return rdev;
> +}
> +
> +static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait)
> +{
> +	int rc;
> +
> +	if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) {
> +		rc = bnxt_re_free_msix(rdev, lock_wait);
> +		if (rc)
> +			dev_warn(rdev_to_dev(rdev),
> +				 "Failed to free MSI-X vectors: %#x", rc);
> +	}
> +	if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags)) {
> +		rc = bnxt_re_unregister_netdev(rdev, lock_wait);
> +		if (rc)
> +			dev_warn(rdev_to_dev(rdev),
> +				 "Failed to unregister with netdev: %#x", rc);
> +	}
> +}
> +
> +static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
> +{
> +	int i, j, rc;
> +
> +	/* Registered a new RoCE device instance to netdev */
> +	rc = bnxt_re_register_netdev(rdev);
> +	if (rc) {
> +		pr_err("Failed to register with netedev: %#x\n", rc);
> +		return -EINVAL;
> +	}
> +	set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
> +
> +	rc = bnxt_re_request_msix(rdev);
> +	if (rc) {
> +		pr_err("Failed to get MSI-X vectors: %#x\n", rc);
> +		rc = -EINVAL;
> +		goto fail;
> +	}
> +	set_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags);
> +
> +	return 0;
> +fail:
> +	bnxt_re_ib_unreg(rdev, true);
> +	return rc;
> +}
> +
> +static void bnxt_re_dev_unreg(struct bnxt_re_dev *rdev)
> +{
> +	struct bnxt_en_dev *en_dev = rdev->en_dev;
> +	struct net_device *netdev = rdev->netdev;
> +
> +	bnxt_re_dev_remove(rdev);
> +
> +	if (netdev)
> +		bnxt_re_dev_unprobe(netdev, en_dev);
> +}
> +
> +static int bnxt_re_dev_reg(struct bnxt_re_dev **rdev, struct net_device *netdev)
> +{
> +	struct bnxt_en_dev *en_dev;
> +	int rc = 0;
> +
> +	if (!is_bnxt_re_dev(netdev))
> +		return -ENODEV;
> +
> +	en_dev = bnxt_re_dev_probe(netdev);
> +	if (IS_ERR(en_dev)) {
> +		pr_err("%s: Failed to probe\n", ROCE_DRV_MODULE_NAME);
> +		rc = PTR_ERR(en_dev);
> +		goto exit;
> +	}
> +	*rdev = bnxt_re_dev_add(netdev, en_dev);
> +	if (!*rdev) {
> +		rc = -ENOMEM;
> +		bnxt_re_dev_unprobe(netdev, en_dev);
> +		goto exit;
> +	}
> +	bnxt_re_hold(*rdev);
> +exit:
> +	return rc;
> +}
> +
> +static void bnxt_re_remove_one(struct bnxt_re_dev *rdev)
> +{
> +	pci_dev_put(rdev->en_dev->pdev);
> +}
> +
> +/* Handle all deferred netevents tasks */
> +static void bnxt_re_task(struct work_struct *work)
> +{
> +	struct bnxt_re_work *re_work;
> +	struct bnxt_re_dev *rdev;
> +	int rc = 0;
> +
> +	re_work = container_of(work, struct bnxt_re_work, work);
> +	rdev = re_work->rdev;
> +
> +	if (re_work->event != NETDEV_REGISTER &&
> +	    !test_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags))
> +		return;
> +
> +	switch (re_work->event) {
> +	case NETDEV_REGISTER:
> +		rc = bnxt_re_ib_reg(rdev);
> +		if (rc)
> +			dev_err(rdev_to_dev(rdev),
> +				"Failed to register with IB: %#x", rc);
> +		break;
> +	case NETDEV_UP:
> +
> +		break;
> +	case NETDEV_DOWN:
> +
> +		break;
> +
> +	case NETDEV_CHANGE:
> +
> +		break;
> +	default:
> +		break;
> +	}

Why do you need empty lines and "break"s between cases?
It can be written as a fallback
case ..:
case ..:
   break;

> +	kfree(re_work);
> +}
> +
> +static void bnxt_re_init_one(struct bnxt_re_dev *rdev)
> +{
> +	pci_dev_get(rdev->en_dev->pdev);
> +}
> +
>  /*
>   * "Notifier chain callback can be invoked for the same chain from
>   * different CPUs at the same time".
> @@ -72,6 +464,62 @@ static struct workqueue_struct *bnxt_re_wq;
>  static int bnxt_re_netdev_event(struct notifier_block *notifier,
>  				unsigned long event, void *ptr)
>  {
> +	struct net_device *real_dev, *netdev = netdev_notifier_info_to_dev(ptr);
> +	struct bnxt_re_work *re_work;
> +	struct bnxt_re_dev *rdev;
> +	int rc = 0;
> +
> +	real_dev = rdma_vlan_dev_real_dev(netdev);
> +	if (!real_dev)
> +		real_dev = netdev;
> +
> +	rdev = bnxt_re_from_netdev(real_dev);
> +	if (!rdev && event != NETDEV_REGISTER)
> +		goto exit;
> +	if (real_dev != netdev)
> +		goto exit;
> +
> +	if (rdev)
> +		bnxt_re_hold(rdev);
> +
> +	switch (event) {
> +	case NETDEV_REGISTER:
> +		if (rdev)
> +			break;
> +		rc = bnxt_re_dev_reg(&rdev, real_dev);
> +		if (rc == -ENODEV)
> +			break;
> +		if (rc) {
> +			pr_err("Failed to register with the device %s: %#x\n",
> +			       real_dev->name, rc);
> +			break;
> +		}
> +		bnxt_re_init_one(rdev);
> +		goto sch_work;
> +
> +	case NETDEV_UNREGISTER:
> +		bnxt_re_ib_unreg(rdev, false);
> +		bnxt_re_remove_one(rdev);
> +		bnxt_re_dev_unreg(rdev);
> +		break;
> +
> +	default:
> +sch_work:

It is very awkward goto label at the middle of switch construction.
Please consider to rewrite it.

> +		/* Allocate for the deferred task */
> +		re_work = kzalloc(sizeof(*re_work), GFP_ATOMIC);
> +		if (!re_work)
> +			break;
> +
> +		re_work->rdev = rdev;
> +		re_work->event = event;
> +		re_work->vlan_dev = (real_dev == netdev ? NULL : netdev);
> +		INIT_WORK(&re_work->work, bnxt_re_task);
> +		queue_work(bnxt_re_wq, &re_work->work);
> +		break;
> +	}
> +	if (rdev)
> +		bnxt_re_put(rdev);
> +exit:
>  	return NOTIFY_DONE;
>  }
>
> --
> 2.5.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] can: ti_hecc: add missing prepare and unprepare of the clock
From: Yegor Yefremov @ 2017-01-18 10:05 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can@vger.kernel.org, netdev, Wolfgang Grandegger
In-Reply-To: <5ccf750a-e468-5c4b-eb26-1e248b712a93@pengutronix.de>

On Wed, Jan 18, 2017 at 11:01 AM, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> On 01/18/2017 10:43 AM, yegorslists@googlemail.com wrote:
>> From: Yegor Yefremov <yegorslists@googlemail.com>
>>
>> In order to make the driver work with the common clock framework, this
>> patch converts the clk_enable()/clk_disable() to
>> clk_prepare_enable()/clk_disable_unprepare().
>>
>
> Can you add the missing error checking for the prepare_enable call?

Will do.

Yegor

>> Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
>> ---
>>  drivers/net/can/ti_hecc.c | 9 +++++----
>>  1 file changed, 5 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
>> index 680d1ff..0448cb5 100644
>> --- a/drivers/net/can/ti_hecc.c
>> +++ b/drivers/net/can/ti_hecc.c
>> @@ -948,7 +948,8 @@ static int ti_hecc_probe(struct platform_device *pdev)
>>       netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
>>               HECC_DEF_NAPI_WEIGHT);
>>
>> -     clk_enable(priv->clk);
>> +     clk_prepare_enable(priv->clk);
>> +
>>       err = register_candev(ndev);
>>       if (err) {
>>               dev_err(&pdev->dev, "register_candev() failed\n");
>> @@ -981,7 +982,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
>>       struct ti_hecc_priv *priv = netdev_priv(ndev);
>>
>>       unregister_candev(ndev);
>> -     clk_disable(priv->clk);
>> +     clk_disable_unprepare(priv->clk);
>>       clk_put(priv->clk);
>>       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>       iounmap(priv->base);
>> @@ -1006,7 +1007,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
>>       hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
>>       priv->can.state = CAN_STATE_SLEEPING;
>>
>> -     clk_disable(priv->clk);
>> +     clk_disable_unprepare(priv->clk);
>>
>>       return 0;
>>  }
>> @@ -1016,7 +1017,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
>>       struct net_device *dev = platform_get_drvdata(pdev);
>>       struct ti_hecc_priv *priv = netdev_priv(dev);
>>
>> -     clk_enable(priv->clk);
>> +     clk_prepare_enable(priv->clk);
>>
>>       hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
>>       priv->can.state = CAN_STATE_ERROR_ACTIVE;
>>
>
>
> --
> Pengutronix e.K.                  | Marc Kleine-Budde           |
> Industrial Linux Solutions        | Phone: +49-231-2826-924     |
> Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
> Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |
>

^ permalink raw reply

* Geschäftsvorschlag
From: tester @ 2017-01-14 23:24 UTC (permalink / raw)
  To: Recipients

Lieber Freund.

Erlauben Sie mir, auf diese Weise auf Sie zuzugehen. Ich bin Dr. Arnold Kristofferson, ein US-Auftragnehmer, der mit Nichtkämpfer US Marine in Ba'qubah, Irak arbeitet. Ich habe die Summe von 10,6 Millionen Dollar, die ich aus einem Rohöl-Deal gemacht habe, und ich möchte, dass Sie mir helfen, es zu erhalten. Da ich hier auf offizieller Kapazität arbeite, kann ich diesen Fonds nicht bei mir behalten und dies ist mein einziger Grund für die Kontaktaufnahme mit Ihnen. Wenn Sie interessiert sind und Sie diesen Fonds in Ihrer Kapazität erhalten können, melden Sie sich bitte bei mir, damit ich Ihnen weitere Details geben kann, wie Sie dieses Geld für mich erhalten können. Bitte erreichen Sie mich per E-Mail: arnoldkristoferson101@gmail.com
Mit freundlichen Grüßen.

^ permalink raw reply

* Re: [PATCH] net: ethernet: stmmac: add ARP management
From: Rayagond Kokatanur @ 2017-01-18 10:19 UTC (permalink / raw)
  To: Christophe Roullier
  Cc: Alexandre Torgue, Giuseppe Cavallaro, netdev, linux-kernel
In-Reply-To: <1484672200-7755-1-git-send-email-christophe.roullier@st.com>

On Tue, Jan 17, 2017 at 10:26 PM, Christophe Roullier
<christophe.roullier@st.com> wrote:
>
> DWC_ether_qos supports the Address Recognition
> Protocol (ARP) Offload for IPv4 packets. This feature
> allows the processing of the IPv4 ARP request packet
> in the receive path and generating corresponding ARP
> response packet in the transmit path. DWC_ether_qos
> generates the ARP reply packets for appropriate ARP
> request packets.
>
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
>  drivers/net/ethernet/stmicro/stmmac/common.h       |  4 ++++
>  drivers/net/ethernet/stmicro/stmmac/dwmac4.h       |  3 +++
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c  | 15 ++++++++++++++
>  drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c   | 23 ++++++++++++++++++++++
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h       |  1 +
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 13 ++++++++++++
>  .../net/ethernet/stmicro/stmmac/stmmac_platform.c  |  1 +
>  include/linux/stmmac.h                             |  1 +
>  8 files changed, 61 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index 75e2666..1d1c815 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -306,6 +306,7 @@ struct dma_features {
>         unsigned int pmt_remote_wake_up;
>         unsigned int pmt_magic_frame;
>         unsigned int rmon;
> +       unsigned int arpoffsel;
>         /* IEEE 1588-2002 */
>         unsigned int time_stamp;
>         /* IEEE 1588-2008 */
> @@ -447,6 +448,7 @@ struct stmmac_dma_ops {
>         void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
>         void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
>         void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
> +       void (*set_arp_addr)(void __iomem *ioaddr, bool en, u32 addr);
>  };
>
>  struct mac_device_info;
> @@ -459,6 +461,8 @@ struct stmmac_ops {
>         int (*rx_ipc)(struct mac_device_info *hw);
>         /* Enable RX Queues */
>         void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
> +       /* Enable and verify that the ARP feature is supported */
> +       int (*arp_en)(struct mac_device_info *hw);
>         /* Dump MAC registers */
>         void (*dump_regs)(struct mac_device_info *hw);
>         /* Handle extra events on specific interrupts hw dependent */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> index db45134..d1e2e37 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> @@ -35,6 +35,7 @@
>  #define GMAC_HW_FEATURE2               0x00000124
>  #define GMAC_MDIO_ADDR                 0x00000200
>  #define GMAC_MDIO_DATA                 0x00000204
> +#define GMAC_ARP_ADDR                  0x00000210
>  #define GMAC_ADDR_HIGH(reg)            (0x300 + reg * 8)
>  #define GMAC_ADDR_LOW(reg)             (0x304 + reg * 8)
>
> @@ -116,6 +117,7 @@ enum power_event {
>  #define GMAC_DEBUG_RPESTS              BIT(0)
>
>  /* MAC config */
> +#define GMAC_CONFIG_ARPEN              BIT(31)
>  #define GMAC_CONFIG_IPC                        BIT(27)
>  #define GMAC_CONFIG_2K                 BIT(22)
>  #define GMAC_CONFIG_ACS                        BIT(20)
> @@ -135,6 +137,7 @@ enum power_event {
>  #define GMAC_HW_FEAT_TXCOSEL           BIT(14)
>  #define GMAC_HW_FEAT_EEESEL            BIT(13)
>  #define GMAC_HW_FEAT_TSSEL             BIT(12)
> +#define GMAC_HW_FEAT_ARPOFFSEL         BIT(9)
>  #define GMAC_HW_FEAT_MMCSEL            BIT(8)
>  #define GMAC_HW_FEAT_MGKSEL            BIT(7)
>  #define GMAC_HW_FEAT_RWKSEL            BIT(6)
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> index 834f40f..33d0fb3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> @@ -102,6 +102,20 @@ static int dwmac4_rx_ipc_enable(struct mac_device_info *hw)
>         return !!(value & GMAC_CONFIG_IPC);
>  }
>
> +static int dwmac4_arp_enable(struct mac_device_info *hw)
> +{
> +       void __iomem *ioaddr = hw->pcsr;
> +       u32 value = readl(ioaddr + GMAC_CONFIG);
> +
> +       value |= GMAC_CONFIG_ARPEN;
> +
> +       writel(value, ioaddr + GMAC_CONFIG);
> +
> +       value = readl(ioaddr + GMAC_CONFIG);
> +
> +       return !!(value & GMAC_CONFIG_ARPEN);
> +}
> +
>  static void dwmac4_pmt(struct mac_device_info *hw, unsigned long mode)
>  {
>         void __iomem *ioaddr = hw->pcsr;
> @@ -463,6 +477,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
>         .core_init = dwmac4_core_init,
>         .rx_ipc = dwmac4_rx_ipc_enable,
>         .rx_queue_enable = dwmac4_rx_queue_enable,
> +       .arp_en = dwmac4_arp_enable,
>         .dump_regs = dwmac4_dump_regs,
>         .host_irq_status = dwmac4_irq_status,
>         .flow_ctrl = dwmac4_flow_ctrl,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> index 377d1b4..fbbd303 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
> @@ -284,6 +284,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
>         dma_cap->pmt_magic_frame = (hw_cap & GMAC_HW_FEAT_MGKSEL) >> 7;
>         /* MMC */
>         dma_cap->rmon = (hw_cap & GMAC_HW_FEAT_MMCSEL) >> 8;
> +       /* ARP */
> +       dma_cap->arpoffsel = (hw_cap & GMAC_HW_FEAT_ARPOFFSEL) >> 9;
>         /* IEEE 1588-2008 */
>         dma_cap->atime_stamp = (hw_cap & GMAC_HW_FEAT_TSSEL) >> 12;
>         /* 802.3az - Energy-Efficient Ethernet (EEE) */
> @@ -331,6 +333,25 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
>         }
>  }
>
> +/* Set ARP Address */
> +static void dwmac4_set_arp_addr(void __iomem *ioaddr, bool set, u32 addr)
> +{
> +       u32 value;
> +
> +       value = readl(ioaddr + GMAC_ARP_ADDR);
> +
> +       if (set) {
> +               /* set arp address */
> +               value = addr;
> +       } else {
> +               /* unset arp address */
> +               value = 0;
> +       }
> +
> +       writel(value, ioaddr + GMAC_ARP_ADDR);
> +       value = readl(ioaddr + GMAC_ARP_ADDR);
> +}
> +
>  const struct stmmac_dma_ops dwmac4_dma_ops = {
>         .reset = dwmac4_dma_reset,
>         .init = dwmac4_dma_init,
> @@ -351,6 +372,7 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
>         .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
>         .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
>         .enable_tso = dwmac4_enable_tso,
> +       .set_arp_addr = dwmac4_set_arp_addr,
>  };
>
>  const struct stmmac_dma_ops dwmac410_dma_ops = {
> @@ -373,4 +395,5 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
>         .set_rx_tail_ptr = dwmac4_set_rx_tail_ptr,
>         .set_tx_tail_ptr = dwmac4_set_tx_tail_ptr,
>         .enable_tso = dwmac4_enable_tso,
> +       .set_arp_addr = dwmac4_set_arp_addr,
>  };
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index bf8a83e..51666fa 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -67,6 +67,7 @@ struct stmmac_priv {
>         bool tx_path_in_lpi_mode;
>         struct timer_list txtimer;
>         bool tso;
> +       int arp;
>
>         struct dma_desc *dma_rx ____cacheline_aligned_in_smp;
>         struct dma_extended_desc *dma_erx;
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index d481c5f..2217dc3 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -3284,6 +3284,19 @@ int stmmac_dvr_probe(struct device *device,
>                 priv->tso = true;
>                 dev_info(priv->device, "TSO feature enabled\n");
>         }
> +
> +       if ((priv->plat->arp_en) && (priv->dma_cap.arpoffsel)) {
> +               ret = priv->hw->mac->arp_en(priv->hw);
> +               if (!ret) {
> +                       pr_warn(" ARP feature disabled\n");
> +               } else {
> +                       pr_info(" ARP feature enabled\n");
> +                       /* Copy MAC addr into MAC_ARP_ADDRESS register*/
> +                       priv->hw->dma->set_arp_addr(priv->ioaddr, 1,
> +                                                   priv->dev->dev_addr);


GMAC_ARP_ADDR register suppose to contains IPv4 address not MAC address.

Also priv->dev->dev_addr will be 6 bytes long but GMAC_ARP_ADDR is 4 bytes long.

What about arp request packet received by device, driver rx poll
should check the arp reply generate by device or not and decide
whehther received arp request packet should be passed to stack or not.
Else stack also ends up trasmiting ARP reply always.


>
> +               }
> +       }
> +
>         ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA;
>         ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
>  #ifdef STMMAC_VLAN_TAG_USED
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 4daa8a3..92a0db9 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -306,6 +306,7 @@ struct plat_stmmacenet_data *
>                 plat->has_gmac = 0;
>                 plat->pmt = 1;
>                 plat->tso_en = of_property_read_bool(np, "snps,tso");
> +               plat->arp_en = of_property_read_bool(np, "snps,arp");
>         }
>
>         if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
> diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
> index d76033d6..2491285 100644
> --- a/include/linux/stmmac.h
> +++ b/include/linux/stmmac.h
> @@ -148,5 +148,6 @@ struct plat_stmmacenet_data {
>         bool tso_en;
>         int mac_port_sel_speed;
>         bool en_tx_lpi_clockgating;
> +       bool arp_en;
>  };
>  #endif
> --
> 1.9.1
>



-- 
wwr
Rayagond

^ permalink raw reply

* Re: Setting link down or up in software
From: Zefir Kurtisi @ 2017-01-18 10:29 UTC (permalink / raw)
  To: Mason, netdev
  Cc: Mans Rullgard, Florian Fainelli, Andrew Lunn, Thibaud Cornic
In-Reply-To: <660b7b17-0136-bf69-fd12-1c125069829b@free.fr>

On 01/13/2017 06:35 PM, Mason wrote:
> On 13/01/2017 17:28, Zefir Kurtisi wrote:
> 
>> As for your specific problem: since I fought myself with the PHY/ETH subsystems
>> over the past months, I might remember something relevant to your issue. Could you
>> give some more info on your setup (PHY driver, opmode (SGMII, RGMII, etc.), ETH).
> 
> Hello Zefir,
> 
> My boards are using these drivers:
> 
> http://lxr.free-electrons.com/source/drivers/net/ethernet/aurora/nb8800.c
> http://lxr.free-electrons.com/source/drivers/net/phy/at803x.c
> 
> The relevant device tree nodes are:
> 
> 		eth0: ethernet@26000 {
> 			compatible = "sigma,smp8734-ethernet";
> 			reg = <0x26000 0x800>;
> 			interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
> 			clocks = <&clkgen SYS_CLK>;
> 		};
> 
> &eth0 {
> 	phy-connection-type = "rgmii";
> 	phy-handle = <&eth0_phy>;
> 	#address-cells = <1>;
> 	#size-cells = <0>;
> 
> 	/* Atheros AR8035 */
> 	eth0_phy: ethernet-phy@4 {
> 		compatible = "ethernet-phy-id004d.d072",
> 			     "ethernet-phy-ieee802.3-c22";
> 		interrupts = <37 IRQ_TYPE_EDGE_RISING>;
> 		reg = <4>;
> 	};
> };
> 
> If I comment the PHY "interrupts" property, then the PHY framework
> falls back to polling.
> 
> Am I forgetting important information?
> 
> Regards.
> 
Hi,

in our system we attach the at8031 over SGMII to the gianfar (Freescale eTSEC) and
to fibre optics transceivers, which operate in fixed speeds. Getting this setup to
work reliably was challenging for various reasons, maybe worth to note

1) fixed SGMII speed not working: link is up on both ends, but no data is passed
2) known issue with SGMII link not completing autonegotiation correctly, see [1]
3) once autoneg is started or chip is reset, MII_CTRL1000 can not be written to
until autoneg is completed => breaks phy state machine when the driver loads with
unplugged cable and tries to set fixed speed

Unless you are using fixed speed links in your setup, none of those should affect
it. My experience with at8031 attached to RGMII is that it is genphy compliant,
therefore I would a) disable interrupts, and b) prevent loading at803x.ko and try
the genphy instead. Yours is an at8035, results may vary.


Cheers,
Zefir


[1] https://www.spinics.net/lists/netdev/msg400804.html

^ permalink raw reply

* [PATCH v2] can: ti_hecc: add missing prepare and unprepare of the clock
From: yegorslists @ 2017-01-18 10:35 UTC (permalink / raw)
  To: linux-can; +Cc: netdev, mkl, wg, Yegor Yefremov

From: Yegor Yefremov <yegorslists@googlemail.com>

In order to make the driver work with the common clock framework, this
patch converts the clk_enable()/clk_disable() to
clk_prepare_enable()/clk_disable_unprepare().

Also add error checking for clk_prepare_enable().

Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
---
Changes v1 -> v2:
	- add error checking for clk_prepare_enable (Marc Kleine-Budde)

 drivers/net/can/ti_hecc.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c
index 680d1ff..8771531 100644
--- a/drivers/net/can/ti_hecc.c
+++ b/drivers/net/can/ti_hecc.c
@@ -948,7 +948,12 @@ static int ti_hecc_probe(struct platform_device *pdev)
 	netif_napi_add(ndev, &priv->napi, ti_hecc_rx_poll,
 		HECC_DEF_NAPI_WEIGHT);
 
-	clk_enable(priv->clk);
+	err = clk_prepare_enable(priv->clk);
+	if (err) {
+		dev_err(&pdev->dev, "clk_prepare_enable() failed\n");
+		goto probe_exit_clk;
+	}
+
 	err = register_candev(ndev);
 	if (err) {
 		dev_err(&pdev->dev, "register_candev() failed\n");
@@ -981,7 +986,7 @@ static int ti_hecc_remove(struct platform_device *pdev)
 	struct ti_hecc_priv *priv = netdev_priv(ndev);
 
 	unregister_candev(ndev);
-	clk_disable(priv->clk);
+	clk_disable_unprepare(priv->clk);
 	clk_put(priv->clk);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	iounmap(priv->base);
@@ -1006,7 +1011,7 @@ static int ti_hecc_suspend(struct platform_device *pdev, pm_message_t state)
 	hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
 	priv->can.state = CAN_STATE_SLEEPING;
 
-	clk_disable(priv->clk);
+	clk_disable_unprepare(priv->clk);
 
 	return 0;
 }
@@ -1016,7 +1021,7 @@ static int ti_hecc_resume(struct platform_device *pdev)
 	struct net_device *dev = platform_get_drvdata(pdev);
 	struct ti_hecc_priv *priv = netdev_priv(dev);
 
-	clk_enable(priv->clk);
+	clk_prepare_enable(priv->clk);
 
 	hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_PDR);
 	priv->can.state = CAN_STATE_ERROR_ACTIVE;
-- 
2.1.4

^ permalink raw reply related

* Re: [PATCH net-next] net/sched: cls_flower: Add user specified data
From: Jamal Hadi Salim @ 2017-01-18 11:06 UTC (permalink / raw)
  To: Paul Blakey, Jiri Pirko
  Cc: John Fastabend, David S. Miller, netdev, Jiri Pirko,
	Hadar Hen Zion, Or Gerlitz, Roi Dayan, Roman Mashak
In-Reply-To: <6be8f641-16ad-88a4-d7c3-474dc3b10e71@mellanox.com>

On 17-01-17 06:53 AM, Paul Blakey wrote:
>
>

>>
>> Should be "trivial" like my patch.
>> Add a new TLV type in TCA_XXX enum in rtnetlink.h
>> in  tc_ctl_tfilter look for it and memcpy it
>> in tcf_fill_node set it on the new TCA_XXX if the cls struct
>> has it present.
>>
>
> That's exactly what I did before I realized it won't work per internal
> element (per handle), which is what I want. see my example.
>
> So I'll probably implement it like actions dumping/init works -
> tcf_exts_init, tcf_exts_dump (calling a generic functions on all
> classifiers who want this).
> I'll add something like get_cookie, dump_cookie. which get/set the
> TCA_COOKIE.
>

Yes, that makes more sense.

cheers,
jamal

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox