Commit 4f159a7c authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-fixes-for-5.18-20220429' of...

Merge tag 'linux-can-fixes-for-5.18-20220429' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can

Marc Kleine-Budde says:

====================
pull-request: can 2022-04-29

The first patch is by Oliver Hartkopp and removes the ability to
re-binding bounds sockets from the ISOTP. It turned out to be not
needed and brings unnecessary complexity.

The last 4 patches all target the grcan driver. Duoming Zhou's patch
fixes a potential dead lock in the grcan_close() function. Daniel
Hellstrom's patch fixes the dma_alloc_coherent() to use the correct
device. Andreas Larsson's 1st patch fixes a broken system id check,
the 2nd patch fixes the NAPI poll budget usage.

* tag 'linux-can-fixes-for-5.18-20220429' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: grcan: only use the NAPI poll budget for RX
  can: grcan: grcan_probe(): fix broken system id check for errata workaround needs
  can: grcan: use ofdev->dev when allocating DMA memory
  can: grcan: grcan_close(): fix deadlock
  can: isotp: remove re-binding of bound socket
====================

Link: https://lore.kernel.org/r/20220429125612.1792561-1-mkl@pengutronix.de


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 249aca0d 2873d4d5
Loading
Loading
Loading
Loading
+24 −22
Original line number Diff line number Diff line
@@ -241,13 +241,14 @@ struct grcan_device_config {
		.rxsize		= GRCAN_DEFAULT_BUFFER_SIZE,	\
		}

#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	0x4100
#define GRCAN_TXBUG_SAFE_GRLIB_VERSION	4100
#define GRLIB_VERSION_MASK		0xffff

/* GRCAN private data structure */
struct grcan_priv {
	struct can_priv can;	/* must be the first member */
	struct net_device *dev;
	struct device *ofdev_dev;
	struct napi_struct napi;

	struct grcan_registers __iomem *regs;	/* ioremap'ed registers */
@@ -921,7 +922,7 @@ static void grcan_free_dma_buffers(struct net_device *dev)
	struct grcan_priv *priv = netdev_priv(dev);
	struct grcan_dma *dma = &priv->dma;

	dma_free_coherent(&dev->dev, dma->base_size, dma->base_buf,
	dma_free_coherent(priv->ofdev_dev, dma->base_size, dma->base_buf,
			  dma->base_handle);
	memset(dma, 0, sizeof(*dma));
}
@@ -946,7 +947,7 @@ static int grcan_allocate_dma_buffers(struct net_device *dev,

	/* Extra GRCAN_BUFFER_ALIGNMENT to allow for alignment */
	dma->base_size = lsize + ssize + GRCAN_BUFFER_ALIGNMENT;
	dma->base_buf = dma_alloc_coherent(&dev->dev,
	dma->base_buf = dma_alloc_coherent(priv->ofdev_dev,
					   dma->base_size,
					   &dma->base_handle,
					   GFP_KERNEL);
@@ -1102,8 +1103,10 @@ static int grcan_close(struct net_device *dev)

	priv->closing = true;
	if (priv->need_txbug_workaround) {
		spin_unlock_irqrestore(&priv->lock, flags);
		del_timer_sync(&priv->hang_timer);
		del_timer_sync(&priv->rr_timer);
		spin_lock_irqsave(&priv->lock, flags);
	}
	netif_stop_queue(dev);
	grcan_stop_hardware(dev);
@@ -1122,7 +1125,7 @@ static int grcan_close(struct net_device *dev)
	return 0;
}

static int grcan_transmit_catch_up(struct net_device *dev, int budget)
static void grcan_transmit_catch_up(struct net_device *dev)
{
	struct grcan_priv *priv = netdev_priv(dev);
	unsigned long flags;
@@ -1130,7 +1133,7 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget)

	spin_lock_irqsave(&priv->lock, flags);

	work_done = catch_up_echo_skb(dev, budget, true);
	work_done = catch_up_echo_skb(dev, -1, true);
	if (work_done) {
		if (!priv->resetting && !priv->closing &&
		    !(priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY))
@@ -1144,8 +1147,6 @@ static int grcan_transmit_catch_up(struct net_device *dev, int budget)
	}

	spin_unlock_irqrestore(&priv->lock, flags);

	return work_done;
}

static int grcan_receive(struct net_device *dev, int budget)
@@ -1227,19 +1228,13 @@ static int grcan_poll(struct napi_struct *napi, int budget)
	struct net_device *dev = priv->dev;
	struct grcan_registers __iomem *regs = priv->regs;
	unsigned long flags;
	int tx_work_done, rx_work_done;
	int rx_budget = budget / 2;
	int tx_budget = budget - rx_budget;
	int work_done;

	/* Half of the budget for receiving messages */
	rx_work_done = grcan_receive(dev, rx_budget);
	work_done = grcan_receive(dev, budget);

	/* Half of the budget for transmitting messages as that can trigger echo
	 * frames being received
	 */
	tx_work_done = grcan_transmit_catch_up(dev, tx_budget);
	grcan_transmit_catch_up(dev);

	if (rx_work_done < rx_budget && tx_work_done < tx_budget) {
	if (work_done < budget) {
		napi_complete(napi);

		/* Guarantee no interference with a running reset that otherwise
@@ -1256,7 +1251,7 @@ static int grcan_poll(struct napi_struct *napi, int budget)
		spin_unlock_irqrestore(&priv->lock, flags);
	}

	return rx_work_done + tx_work_done;
	return work_done;
}

/* Work tx bug by waiting while for the risky situation to clear. If that fails,
@@ -1587,6 +1582,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev,
	memcpy(&priv->config, &grcan_module_config,
	       sizeof(struct grcan_device_config));
	priv->dev = dev;
	priv->ofdev_dev = &ofdev->dev;
	priv->regs = base;
	priv->can.bittiming_const = &grcan_bittiming_const;
	priv->can.do_set_bittiming = grcan_set_bittiming;
@@ -1639,6 +1635,7 @@ static int grcan_setup_netdev(struct platform_device *ofdev,
static int grcan_probe(struct platform_device *ofdev)
{
	struct device_node *np = ofdev->dev.of_node;
	struct device_node *sysid_parent;
	u32 sysid, ambafreq;
	int irq, err;
	void __iomem *base;
@@ -1647,10 +1644,15 @@ static int grcan_probe(struct platform_device *ofdev)
	/* Compare GRLIB version number with the first that does not
	 * have the tx bug (see start_xmit)
	 */
	err = of_property_read_u32(np, "systemid", &sysid);
	if (!err && ((sysid & GRLIB_VERSION_MASK)
		     >= GRCAN_TXBUG_SAFE_GRLIB_VERSION))
	sysid_parent = of_find_node_by_path("/ambapp0");
	if (sysid_parent) {
		of_node_get(sysid_parent);
		err = of_property_read_u32(sysid_parent, "systemid", &sysid);
		if (!err && ((sysid & GRLIB_VERSION_MASK) >=
			     GRCAN_TXBUG_SAFE_GRLIB_VERSION))
			txbug = false;
		of_node_put(sysid_parent);
	}

	err = of_property_read_u32(np, "freq", &ambafreq);
	if (err) {
+5 −20
Original line number Diff line number Diff line
@@ -1189,6 +1189,11 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)

	lock_sock(sk);

	if (so->bound) {
		err = -EINVAL;
		goto out;
	}

	/* do not register frame reception for functional addressing */
	if (so->opt.flags & CAN_ISOTP_SF_BROADCAST)
		do_rx_reg = 0;
@@ -1199,10 +1204,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
		goto out;
	}

	if (so->bound && addr->can_ifindex == so->ifindex &&
	    rx_id == so->rxid && tx_id == so->txid)
		goto out;

	dev = dev_get_by_index(net, addr->can_ifindex);
	if (!dev) {
		err = -ENODEV;
@@ -1237,22 +1238,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)

	dev_put(dev);

	if (so->bound && do_rx_reg) {
		/* unregister old filter */
		if (so->ifindex) {
			dev = dev_get_by_index(net, so->ifindex);
			if (dev) {
				can_rx_unregister(net, dev, so->rxid,
						  SINGLE_MASK(so->rxid),
						  isotp_rcv, sk);
				can_rx_unregister(net, dev, so->txid,
						  SINGLE_MASK(so->txid),
						  isotp_rcv_echo, sk);
				dev_put(dev);
			}
		}
	}

	/* switch to new settings */
	so->ifindex = ifindex;
	so->rxid = rx_id;