Skip to content

Commit

Permalink
can: dev: can_free_echo_skb(): extend to return can frame length
Browse files Browse the repository at this point in the history
In order to implement byte queue limits (bql) in CAN drivers, the
length of the CAN frame needs to be passed into the networking stack
even if the transmission failed for some reason.

To avoid to calculate this length twice, extend can_free_echo_skb() to
return that value. Convert all users of this function, too.

This patch is the natural extension of commit:

| 9420e1d ("can: dev: can_get_echo_skb(): extend to return can
|                frame length")

Link: https://lore.kernel.org/r/20210319142700.305648-3-mkl@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
  • Loading branch information
Marc Kleine-Budde committed Mar 30, 2021
1 parent 4168d07 commit f318482
Show file tree
Hide file tree
Showing 17 changed files with 29 additions and 21 deletions.
11 changes: 9 additions & 2 deletions drivers/net/can/dev/skb.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
*
* The function is typically called when TX failed.
*/
void can_free_echo_skb(struct net_device *dev, unsigned int idx)
void can_free_echo_skb(struct net_device *dev, unsigned int idx,
unsigned int *frame_len_ptr)
{
struct can_priv *priv = netdev_priv(dev);

Expand All @@ -164,7 +165,13 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx)
}

if (priv->echo_skb[idx]) {
dev_kfree_skb_any(priv->echo_skb[idx]);
struct sk_buff *skb = priv->echo_skb[idx];
struct can_skb_priv *can_skb_priv = can_skb_prv(skb);

if (frame_len_ptr)
*frame_len_ptr = can_skb_priv->frame_len;

dev_kfree_skb_any(skb);
priv->echo_skb[idx] = NULL;
}
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/grcan.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ static int catch_up_echo_skb(struct net_device *dev, int budget, bool echo)
can_get_echo_skb(dev, i, NULL);
} else {
/* For cleanup of untransmitted messages */
can_free_echo_skb(dev, i);
can_free_echo_skb(dev, i, NULL);
}

priv->eskbp = grcan_ring_add(priv->eskbp, GRCAN_MSG_SIZE,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/m_can/m_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ static void m_can_clean(struct net_device *net)
putidx = ((m_can_read(cdev, M_CAN_TXFQS) &
TXFQS_TFQPI_MASK) >> TXFQS_TFQPI_SHIFT);

can_free_echo_skb(cdev->net, putidx);
can_free_echo_skb(cdev->net, putidx, NULL);
cdev->tx_skb = NULL;
}
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/rcar/rcar_can.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static void tx_failure_cleanup(struct net_device *ndev)
int i;

for (i = 0; i < RCAR_CAN_FIFO_DEPTH; i++)
can_free_echo_skb(ndev, i);
can_free_echo_skb(ndev, i, NULL);
}

static void rcar_can_error(struct net_device *ndev)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/rcar/rcar_canfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ static void rcar_canfd_tx_failure_cleanup(struct net_device *ndev)
u32 i;

for (i = 0; i < RCANFD_FIFO_DEPTH; i++)
can_free_echo_skb(ndev, i);
can_free_echo_skb(ndev, i, NULL);
}

static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/sja1000/sja1000.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT &&
!(status & SR_TCS)) {
stats->tx_errors++;
can_free_echo_skb(dev, 0);
can_free_echo_skb(dev, 0, NULL);
} else {
/* transmission complete */
stats->tx_bytes +=
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/spi/hi311x.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ static void hi3110_clean(struct net_device *net)
net->stats.tx_errors++;
dev_kfree_skb(priv->tx_skb);
if (priv->tx_len)
can_free_echo_skb(priv->net, 0);
can_free_echo_skb(priv->net, 0, NULL);
priv->tx_skb = NULL;
priv->tx_len = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/spi/mcp251x.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ static void mcp251x_clean(struct net_device *net)
net->stats.tx_errors++;
dev_kfree_skb(priv->tx_skb);
if (priv->tx_len)
can_free_echo_skb(priv->net, 0);
can_free_echo_skb(priv->net, 0, NULL);
priv->tx_skb = NULL;
priv->tx_len = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/usb/ems_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne

err = usb_submit_urb(urb, GFP_ATOMIC);
if (unlikely(err)) {
can_free_echo_skb(netdev, context->echo_index);
can_free_echo_skb(netdev, context->echo_index, NULL);

usb_unanchor_urb(urb);
usb_free_coherent(dev->udev, size, buf, urb->transfer_dma);
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/can/usb/esd_usb2.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ static void esd_usb2_tx_done_msg(struct esd_usb2_net_priv *priv,
can_get_echo_skb(netdev, context->echo_index, NULL);
} else {
stats->tx_errors++;
can_free_echo_skb(netdev, context->echo_index);
can_free_echo_skb(netdev, context->echo_index, NULL);
}

/* Release context */
Expand Down Expand Up @@ -793,7 +793,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb,

err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
can_free_echo_skb(netdev, context->echo_index);
can_free_echo_skb(netdev, context->echo_index, NULL);

atomic_dec(&priv->active_tx_jobs);
usb_unanchor_urb(urb);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/usb/gs_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
if (unlikely(rc)) { /* usb send failed */
atomic_dec(&dev->active_tx_urbs);

can_free_echo_skb(netdev, idx);
can_free_echo_skb(netdev, idx, NULL);
gs_free_tx_context(txc);

usb_unanchor_urb(urb);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (unlikely(err)) {
spin_lock_irqsave(&priv->tx_contexts_lock, flags);

can_free_echo_skb(netdev, context->echo_index);
can_free_echo_skb(netdev, context->echo_index, NULL);
context->echo_index = dev->max_tx_urbs;
--priv->active_tx_contexts;
netif_wake_queue(netdev);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/usb/mcba_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ static netdev_tx_t mcba_usb_start_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;

xmit_failed:
can_free_echo_skb(priv->netdev, ctx->ndx);
can_free_echo_skb(priv->netdev, ctx->ndx, NULL);
mcba_usb_free_ctx(ctx);
dev_kfree_skb(skb);
stats->tx_dropped++;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/usb/peak_usb/pcan_usb_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb,

err = usb_submit_urb(urb, GFP_ATOMIC);
if (err) {
can_free_echo_skb(netdev, context->echo_index);
can_free_echo_skb(netdev, context->echo_index, NULL);

usb_unanchor_urb(urb);

Expand Down
6 changes: 3 additions & 3 deletions drivers/net/can/usb/ucan.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ static void ucan_tx_complete_msg(struct ucan_priv *up,
can_get_echo_skb(up->netdev, echo_index, NULL);
} else {
up->netdev->stats.tx_dropped++;
can_free_echo_skb(up->netdev, echo_index);
can_free_echo_skb(up->netdev, echo_index, NULL);
}
spin_unlock_irqrestore(&up->echo_skb_lock, flags);
}
Expand Down Expand Up @@ -843,7 +843,7 @@ static void ucan_write_bulk_callback(struct urb *urb)

/* update counters an cleanup */
spin_lock_irqsave(&up->echo_skb_lock, flags);
can_free_echo_skb(up->netdev, context - up->context_array);
can_free_echo_skb(up->netdev, context - up->context_array, NULL);
spin_unlock_irqrestore(&up->echo_skb_lock, flags);

up->netdev->stats.tx_dropped++;
Expand Down Expand Up @@ -1157,7 +1157,7 @@ static netdev_tx_t ucan_start_xmit(struct sk_buff *skb,
* frees the skb
*/
spin_lock_irqsave(&up->echo_skb_lock, flags);
can_free_echo_skb(up->netdev, echo_index);
can_free_echo_skb(up->netdev, echo_index, NULL);
spin_unlock_irqrestore(&up->echo_skb_lock, flags);

if (ret == -ENODEV) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/can/usb/usb_8dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ static netdev_tx_t usb_8dev_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;

failed:
can_free_echo_skb(netdev, context->echo_index);
can_free_echo_skb(netdev, context->echo_index, NULL);

usb_unanchor_urb(urb);
usb_free_coherent(priv->udev, size, buf, urb->transfer_dma);
Expand Down
3 changes: 2 additions & 1 deletion include/linux/can/skb.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ struct sk_buff *__can_get_echo_skb(struct net_device *dev, unsigned int idx,
u8 *len_ptr, unsigned int *frame_len_ptr);
unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx,
unsigned int *frame_len_ptr);
void can_free_echo_skb(struct net_device *dev, unsigned int idx);
void can_free_echo_skb(struct net_device *dev, unsigned int idx,
unsigned int *frame_len_ptr);
struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
struct sk_buff *alloc_canfd_skb(struct net_device *dev,
struct canfd_frame **cfd);
Expand Down

0 comments on commit f318482

Please sign in to comment.