Skip to content

Commit

Permalink
Merge branch 'net-thunderbolt-add-tracepoints'
Browse files Browse the repository at this point in the history
Mika Westerberg says:

====================
net: thunderbolt: Add tracepoints

This series adds tracepoints and additional logging to the
Thunderbolt/USB4 networking driver. These are useful when debugging
possible issues.

Before that we move the driver into its own directory under drivers/net
so that we can add additional files without trashing the network drivers
main directory, and update the MAINTAINERS accordingly.

v1: https://lore.kernel.org/netdev/20230104081731.45928-1-mika.westerberg@linux.intel.com/
====================

Link: https://lore.kernel.org/r/20230111062633.1385-1-mika.westerberg@linux.intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Jan 13, 2023
2 parents dec5efc + f758652 commit 296403f
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 17 deletions.
2 changes: 1 addition & 1 deletion MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -20789,7 +20789,7 @@ M: Mika Westerberg <mika.westerberg@linux.intel.com>
M: Yehezkel Bernat <YehezkelShB@gmail.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/thunderbolt.c
F: drivers/net/thunderbolt/

THUNDERX GPIO DRIVER
M: Robert Richter <rric@kernel.org>
Expand Down
13 changes: 1 addition & 12 deletions drivers/net/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -583,18 +583,7 @@ config FUJITSU_ES
This driver provides support for Extended Socket network device
on Extended Partitioning of FUJITSU PRIMEQUEST 2000 E2 series.

config USB4_NET
tristate "Networking over USB4 and Thunderbolt cables"
depends on USB4 && INET
help
Select this if you want to create network between two computers
over a USB4 and Thunderbolt cables. The driver supports Apple
ThunderboltIP protocol and allows communication with any host
supporting the same protocol including Windows and macOS.

To compile this driver a module, choose M here. The module will be
called thunderbolt-net.

source "drivers/net/thunderbolt/Kconfig"
source "drivers/net/hyperv/Kconfig"

config NETDEVSIM
Expand Down
4 changes: 1 addition & 3 deletions drivers/net/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ obj-$(CONFIG_HYPERV_NET) += hyperv/
obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o

obj-$(CONFIG_FUJITSU_ES) += fjes/

thunderbolt-net-y += thunderbolt.o
obj-$(CONFIG_USB4_NET) += thunderbolt-net.o
obj-$(CONFIG_USB4_NET) += thunderbolt/
obj-$(CONFIG_NETDEVSIM) += netdevsim/
obj-$(CONFIG_NET_FAILOVER) += net_failover.o
12 changes: 12 additions & 0 deletions drivers/net/thunderbolt/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-only
config USB4_NET
tristate "Networking over USB4 and Thunderbolt cables"
depends on USB4 && INET
help
Select this if you want to create network between two computers
over a USB4 and Thunderbolt cables. The driver supports Apple
ThunderboltIP protocol and allows communication with any host
supporting the same protocol including Windows and macOS.

To compile this driver a module, choose M here. The module will be
called thunderbolt_net.
6 changes: 6 additions & 0 deletions drivers/net/thunderbolt/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_USB4_NET) := thunderbolt_net.o
thunderbolt_net-objs := main.o trace.o

# Tracepoints need to know where to find trace.h
CFLAGS_trace.o := -I$(src)
48 changes: 47 additions & 1 deletion drivers/net/thunderbolt.c → drivers/net/thunderbolt/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

#include <net/ip6_checksum.h>

#include "trace.h"

/* Protocol timeouts in ms */
#define TBNET_LOGIN_DELAY 4500
#define TBNET_LOGIN_TIMEOUT 500
Expand Down Expand Up @@ -305,6 +307,8 @@ static int tbnet_logout_request(struct tbnet *net)

static void start_login(struct tbnet *net)
{
netdev_dbg(net->dev, "login started\n");

mutex_lock(&net->connection_lock);
net->login_sent = false;
net->login_received = false;
Expand All @@ -318,6 +322,8 @@ static void stop_login(struct tbnet *net)
{
cancel_delayed_work_sync(&net->login_work);
cancel_work_sync(&net->connected_work);

netdev_dbg(net->dev, "login stopped\n");
}

static inline unsigned int tbnet_frame_size(const struct tbnet_frame *tf)
Expand Down Expand Up @@ -349,6 +355,8 @@ static void tbnet_free_buffers(struct tbnet_ring *ring)
size = TBNET_RX_PAGE_SIZE;
}

trace_tbnet_free_frame(i, tf->page, tf->frame.buffer_phy, dir);

if (tf->frame.buffer_phy)
dma_unmap_page(dma_dev, tf->frame.buffer_phy, size,
dir);
Expand All @@ -374,6 +382,8 @@ static void tbnet_tear_down(struct tbnet *net, bool send_logout)
int ret, retries = TBNET_LOGOUT_RETRIES;

while (send_logout && retries-- > 0) {
netdev_dbg(net->dev, "sending logout request %u\n",
retries);
ret = tbnet_logout_request(net);
if (ret != -ETIMEDOUT)
break;
Expand All @@ -400,6 +410,8 @@ static void tbnet_tear_down(struct tbnet *net, bool send_logout)
net->login_sent = false;
net->login_received = false;

netdev_dbg(net->dev, "network traffic stopped\n");

mutex_unlock(&net->connection_lock);
}

Expand Down Expand Up @@ -431,12 +443,15 @@ static int tbnet_handle_packet(const void *buf, size_t size, void *data)

switch (pkg->hdr.type) {
case TBIP_LOGIN:
netdev_dbg(net->dev, "remote login request received\n");
if (!netif_running(net->dev))
break;

ret = tbnet_login_response(net, route, sequence,
pkg->hdr.command_id);
if (!ret) {
netdev_dbg(net->dev, "remote login response sent\n");

mutex_lock(&net->connection_lock);
net->login_received = true;
net->remote_transmit_path = pkg->transmit_path;
Expand All @@ -458,9 +473,12 @@ static int tbnet_handle_packet(const void *buf, size_t size, void *data)
break;

case TBIP_LOGOUT:
netdev_dbg(net->dev, "remote logout request received\n");
ret = tbnet_logout_response(net, route, sequence, command_id);
if (!ret)
if (!ret) {
netdev_dbg(net->dev, "remote logout response sent\n");
queue_work(system_long_wq, &net->disconnect_work);
}
break;

default:
Expand Down Expand Up @@ -512,6 +530,9 @@ static int tbnet_alloc_rx_buffers(struct tbnet *net, unsigned int nbuffers)
tf->frame.buffer_phy = dma_addr;
tf->dev = net->dev;

trace_tbnet_alloc_rx_frame(index, tf->page, dma_addr,
DMA_FROM_DEVICE);

tb_ring_rx(ring->ring, &tf->frame);

ring->prod++;
Expand Down Expand Up @@ -588,6 +609,8 @@ static int tbnet_alloc_tx_buffers(struct tbnet *net)
tf->frame.callback = tbnet_tx_callback;
tf->frame.sof = TBIP_PDF_FRAME_START;
tf->frame.eof = TBIP_PDF_FRAME_END;

trace_tbnet_alloc_tx_frame(i, tf->page, dma_addr, DMA_TO_DEVICE);
}

ring->cons = 0;
Expand All @@ -612,6 +635,8 @@ static void tbnet_connected_work(struct work_struct *work)
if (!connected)
return;

netdev_dbg(net->dev, "login successful, enabling paths\n");

ret = tb_xdomain_alloc_in_hopid(net->xd, net->remote_transmit_path);
if (ret != net->remote_transmit_path) {
netdev_err(net->dev, "failed to allocate Rx HopID\n");
Expand Down Expand Up @@ -647,6 +672,8 @@ static void tbnet_connected_work(struct work_struct *work)

netif_carrier_on(net->dev);
netif_start_queue(net->dev);

netdev_dbg(net->dev, "network traffic started\n");
return;

err_free_tx_buffers:
Expand All @@ -668,15 +695,22 @@ static void tbnet_login_work(struct work_struct *work)
if (netif_carrier_ok(net->dev))
return;

netdev_dbg(net->dev, "sending login request, retries=%u\n",
net->login_retries);

ret = tbnet_login_request(net, net->login_retries % 4);
if (ret) {
netdev_dbg(net->dev, "sending login request failed, ret=%d\n",
ret);
if (net->login_retries++ < TBNET_LOGIN_RETRIES) {
queue_delayed_work(system_long_wq, &net->login_work,
delay);
} else {
netdev_info(net->dev, "ThunderboltIP login timed out\n");
}
} else {
netdev_dbg(net->dev, "received login reply\n");

net->login_retries = 0;

mutex_lock(&net->connection_lock);
Expand Down Expand Up @@ -807,12 +841,16 @@ static int tbnet_poll(struct napi_struct *napi, int budget)

hdr = page_address(page);
if (!tbnet_check_frame(net, tf, hdr)) {
trace_tbnet_invalid_rx_ip_frame(hdr->frame_size,
hdr->frame_id, hdr->frame_index, hdr->frame_count);
__free_pages(page, TBNET_RX_PAGE_ORDER);
dev_kfree_skb_any(net->skb);
net->skb = NULL;
continue;
}

trace_tbnet_rx_ip_frame(hdr->frame_size, hdr->frame_id,
hdr->frame_index, hdr->frame_count);
frame_size = le32_to_cpu(hdr->frame_size);

skb = net->skb;
Expand Down Expand Up @@ -846,6 +884,7 @@ static int tbnet_poll(struct napi_struct *napi, int budget)

if (last) {
skb->protocol = eth_type_trans(skb, net->dev);
trace_tbnet_rx_skb(skb);
napi_gro_receive(&net->napi, skb);
net->skb = NULL;
}
Expand Down Expand Up @@ -965,6 +1004,8 @@ static bool tbnet_xmit_csum_and_map(struct tbnet *net, struct sk_buff *skb,
for (i = 0; i < frame_count; i++) {
hdr = page_address(frames[i]->page);
hdr->frame_count = cpu_to_le32(frame_count);
trace_tbnet_tx_ip_frame(hdr->frame_size, hdr->frame_id,
hdr->frame_index, hdr->frame_count);
dma_sync_single_for_device(dma_dev,
frames[i]->frame.buffer_phy,
tbnet_frame_size(frames[i]), DMA_TO_DEVICE);
Expand Down Expand Up @@ -1029,6 +1070,8 @@ static bool tbnet_xmit_csum_and_map(struct tbnet *net, struct sk_buff *skb,
len = le32_to_cpu(hdr->frame_size) - offset;
wsum = csum_partial(dest, len, wsum);
hdr->frame_count = cpu_to_le32(frame_count);
trace_tbnet_tx_ip_frame(hdr->frame_size, hdr->frame_id,
hdr->frame_index, hdr->frame_count);

offset = 0;
}
Expand Down Expand Up @@ -1071,6 +1114,8 @@ static netdev_tx_t tbnet_start_xmit(struct sk_buff *skb,
bool unmap = false;
void *dest;

trace_tbnet_tx_skb(skb);

nframes = DIV_ROUND_UP(data_len, TBNET_MAX_PAYLOAD_SIZE);
if (tbnet_available_buffers(&net->tx_ring) < nframes) {
netif_stop_queue(net->dev);
Expand Down Expand Up @@ -1177,6 +1222,7 @@ static netdev_tx_t tbnet_start_xmit(struct sk_buff *skb,
net->stats.tx_packets++;
net->stats.tx_bytes += skb->len;

trace_tbnet_consume_skb(skb);
dev_consume_skb_any(skb);

return NETDEV_TX_OK;
Expand Down
10 changes: 10 additions & 0 deletions drivers/net/thunderbolt/trace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Tracepoints for Thunderbolt/USB4 networking driver
*
* Copyright (C) 2023, Intel Corporation
* Author: Mika Westerberg <mika.westerberg@linux.intel.com>
*/

#define CREATE_TRACE_POINTS
#include "trace.h"
Loading

0 comments on commit 296403f

Please sign in to comment.