Commit de90869a authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge tag 'linux-can-fixes-for-6.1-20221027' of...

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

Marc Kleine-Budde says:

====================
pull-request: can 2022-10-27

Anssi Hannula fixes the use of the completions in the kvaser_usb
driver.

Biju Das contributes 2 patches for the rcar_canfd driver. A IRQ storm
that can be triggered by high CAN bus load and channel specific IRQ
handlers are fixed.

Yang Yingliang fixes the j1939 transport protocol by moving a
kfree_skb() out of a spin_lock_irqsave protected section.

* tag 'linux-can-fixes-for-6.1-20221027' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can:
  can: j1939: transport: j1939_session_skb_drop_old(): spin_unlock_irqrestore() before kfree_skb()
  can: rcar_canfd: fix channel specific IRQ handling for RZ/G2L
  can: rcar_canfd: rcar_canfd_handle_global_receive(): fix IRQ storm on global FIFO receive
  can: kvaser_usb: Fix possible completions during init_completion
====================

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


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents ef3556ee c3c06c61
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -1157,11 +1157,13 @@ static void rcar_canfd_handle_global_receive(struct rcar_canfd_global *gpriv, u3
{
	struct rcar_canfd_channel *priv = gpriv->ch[ch];
	u32 ridx = ch + RCANFD_RFFIFO_IDX;
	u32 sts;
	u32 sts, cc;

	/* Handle Rx interrupts */
	sts = rcar_canfd_read(priv->base, RCANFD_RFSTS(gpriv, ridx));
	if (likely(sts & RCANFD_RFSTS_RFIF)) {
	cc = rcar_canfd_read(priv->base, RCANFD_RFCC(gpriv, ridx));
	if (likely(sts & RCANFD_RFSTS_RFIF &&
		   cc & RCANFD_RFCC_RFIE)) {
		if (napi_schedule_prep(&priv->napi)) {
			/* Disable Rx FIFO interrupts */
			rcar_canfd_clear_bit(priv->base,
@@ -1244,11 +1246,9 @@ static void rcar_canfd_handle_channel_tx(struct rcar_canfd_global *gpriv, u32 ch

static irqreturn_t rcar_canfd_channel_tx_interrupt(int irq, void *dev_id)
{
	struct rcar_canfd_global *gpriv = dev_id;
	u32 ch;
	struct rcar_canfd_channel *priv = dev_id;

	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
		rcar_canfd_handle_channel_tx(gpriv, ch);
	rcar_canfd_handle_channel_tx(priv->gpriv, priv->channel);

	return IRQ_HANDLED;
}
@@ -1276,11 +1276,9 @@ static void rcar_canfd_handle_channel_err(struct rcar_canfd_global *gpriv, u32 c

static irqreturn_t rcar_canfd_channel_err_interrupt(int irq, void *dev_id)
{
	struct rcar_canfd_global *gpriv = dev_id;
	u32 ch;
	struct rcar_canfd_channel *priv = dev_id;

	for_each_set_bit(ch, &gpriv->channels_mask, gpriv->max_channels)
		rcar_canfd_handle_channel_err(gpriv, ch);
	rcar_canfd_handle_channel_err(priv->gpriv, priv->channel);

	return IRQ_HANDLED;
}
@@ -1721,6 +1719,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
	priv->ndev = ndev;
	priv->base = gpriv->base;
	priv->channel = ch;
	priv->gpriv = gpriv;
	priv->can.clock.freq = fcan_freq;
	dev_info(&pdev->dev, "can_clk rate is %u\n", priv->can.clock.freq);

@@ -1749,7 +1748,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
		}
		err = devm_request_irq(&pdev->dev, err_irq,
				       rcar_canfd_channel_err_interrupt, 0,
				       irq_name, gpriv);
				       irq_name, priv);
		if (err) {
			dev_err(&pdev->dev, "devm_request_irq CH Err(%d) failed, error %d\n",
				err_irq, err);
@@ -1763,7 +1762,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,
		}
		err = devm_request_irq(&pdev->dev, tx_irq,
				       rcar_canfd_channel_tx_interrupt, 0,
				       irq_name, gpriv);
				       irq_name, priv);
		if (err) {
			dev_err(&pdev->dev, "devm_request_irq Tx (%d) failed, error %d\n",
				tx_irq, err);
@@ -1789,7 +1788,6 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch,

	priv->can.do_set_mode = rcar_canfd_do_set_mode;
	priv->can.do_get_berr_counter = rcar_canfd_get_berr_counter;
	priv->gpriv = gpriv;
	SET_NETDEV_DEV(ndev, &pdev->dev);

	netif_napi_add_weight(ndev, &priv->napi, rcar_canfd_rx_poll,
+2 −2
Original line number Diff line number Diff line
@@ -1875,7 +1875,7 @@ static int kvaser_usb_hydra_start_chip(struct kvaser_usb_net_priv *priv)
{
	int err;

	init_completion(&priv->start_comp);
	reinit_completion(&priv->start_comp);

	err = kvaser_usb_hydra_send_simple_cmd(priv->dev, CMD_START_CHIP_REQ,
					       priv->channel);
@@ -1893,7 +1893,7 @@ static int kvaser_usb_hydra_stop_chip(struct kvaser_usb_net_priv *priv)
{
	int err;

	init_completion(&priv->stop_comp);
	reinit_completion(&priv->stop_comp);

	/* Make sure we do not report invalid BUS_OFF from CMD_CHIP_STATE_EVENT
	 * see comment in kvaser_usb_hydra_update_state()
+2 −2
Original line number Diff line number Diff line
@@ -1320,7 +1320,7 @@ static int kvaser_usb_leaf_start_chip(struct kvaser_usb_net_priv *priv)
{
	int err;

	init_completion(&priv->start_comp);
	reinit_completion(&priv->start_comp);

	err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_START_CHIP,
					      priv->channel);
@@ -1338,7 +1338,7 @@ static int kvaser_usb_leaf_stop_chip(struct kvaser_usb_net_priv *priv)
{
	int err;

	init_completion(&priv->stop_comp);
	reinit_completion(&priv->stop_comp);

	err = kvaser_usb_leaf_send_simple_cmd(priv->dev, CMD_STOP_CHIP,
					      priv->channel);
+3 −1
Original line number Diff line number Diff line
@@ -342,11 +342,13 @@ static void j1939_session_skb_drop_old(struct j1939_session *session)
		__skb_unlink(do_skb, &session->skb_queue);
		/* drop ref taken in j1939_session_skb_queue() */
		skb_unref(do_skb);
		spin_unlock_irqrestore(&session->skb_queue.lock, flags);

		kfree_skb(do_skb);
	}
	} else {
		spin_unlock_irqrestore(&session->skb_queue.lock, flags);
	}
}

void j1939_session_skb_queue(struct j1939_session *session,
			     struct sk_buff *skb)