From: Jeremy Kerr <jk@codeconstruct.com.au>
To: Adam Young <admiyo@os.amperecomputing.com>,
Matt Johnston <matt@codeconstruct.com.au>,
Andrew Lunn <andrew+netdev@lunn.ch>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Sudeep Holla <sudeep.holla@arm.com>,
Jonathan Cameron <Jonathan.Cameron@huawei.com>,
Huisong Li <lihuisong@huawei.com>
Subject: Re: [net-next v39] mctp pcc: Implement MCTP over PCC Transport
Date: Thu, 07 May 2026 11:02:42 +0800 [thread overview]
Message-ID: <04015745fb7223f6d7dc262ae505daf0272586fb.camel@codeconstruct.com.au> (raw)
In-Reply-To: <20260506214327.276069-1-admiyo@os.amperecomputing.com>
Hi Adam,
> +static void mctp_pcc_client_rx_callback(struct mbox_client *cl, void *mssg)
> +{
> + struct acpi_pcct_ext_pcc_shared_memory pcc_header;
> + struct mctp_pcc_ndev *mctp_pcc_ndev;
> + struct mctp_pcc_mailbox *inbox;
> + struct mctp_skb_cb *cb;
> + struct sk_buff *skb;
> + u32 header_length;
> + int size;
> +
> + mctp_pcc_ndev = container_of(cl, struct mctp_pcc_ndev, inbox.client);
> + inbox = &mctp_pcc_ndev->inbox;
> + memcpy_fromio(&pcc_header, inbox->chan->shmem, sizeof(pcc_header));
> +
> + // The message must at least have the PCC command indicating it is an MCTP
> + // message followed by the MCTP header, or we have a malformed message.
> + // This may be run on big endian system, but the data in the buffer is
> + // explicitly little endian.
> + header_length = le32_to_cpu(pcc_header.length);
> + if (header_length < sizeof(pcc_header.command) + sizeof(struct mctp_hdr)) {
> + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
> + // If the reported size is larger than the shared memory minus headers,
> + // something is wrong and treat the buffer as corrupted data.
> + if (header_length > inbox->chan->shmem_size - PCC_EXTRA_LEN) {
> + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
> + if (memcmp(&pcc_header.command, MCTP_SIGNATURE, MCTP_SIGNATURE_LENGTH) != 0) {
> + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
> +
> + size = header_length + PCC_EXTRA_LEN;
> + skb = netdev_alloc_skb(mctp_pcc_ndev->ndev, size);
> + if (!skb) {
> + dev_dstats_rx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
Minor, but you have four instances of the dstats_rx_dropped call, that
may work as a shared error path.
> + skb_put(skb, size);
> + skb->protocol = htons(ETH_P_MCTP);
> + memcpy_fromio(skb->data, inbox->chan->shmem, size);
> + dev_dstats_rx_add(mctp_pcc_ndev->ndev, size);
> + skb_pull(skb, sizeof(pcc_header));
> + skb_reset_mac_header(skb);
> + skb_reset_network_header(skb);
> + cb = __mctp_cb(skb);
> + cb->halen = 0;
> + netif_rx(skb);
> +}
> +
> +static netdev_tx_t mctp_pcc_tx(struct sk_buff *skb, struct net_device *ndev)
> +{
> + struct acpi_pcct_ext_pcc_shared_memory *pcc_header;
> + struct mctp_pcc_ndev *mpnd = netdev_priv(ndev);
> + int len = skb->len;
> +
> + /* Consolidated a fragmented packet into contiguous memory */
> + if (skb_is_nonlinear(skb)) {
> + if (skb_linearize(skb))
> + goto error;
> + }
skb_linearize() already has the skb_is_nonlinear() check.
However, you don't need to call skb_linearize() anyway, as that will
happen for you in validate_xmit_skb(), since the driver does not
advertise support for nonlinear skbs.
> +
> + if (skb_cow_head(skb, sizeof(*pcc_header)))
> + goto error;
> +
> + /**
> + * This code could potentially be run on A Big Endian
> + * System. The ACPI specification requires that values
> + * in the shared buffer be little endian.
> + */
Minor, but I don't think this comment is necessary.
More importantly though, you're getting a bunch of warnings from the use
of these endian helpers:
drivers/net/mctp/mctp-pcc.c:70:25: warning: cast to restricted __le32
drivers/net/mctp/mctp-pcc.c:125:31: warning: incorrect type in assignment (different base types)
drivers/net/mctp/mctp-pcc.c:125:31: expected unsigned int [usertype] signature
drivers/net/mctp/mctp-pcc.c:125:31: got restricted __le32 [usertype]
drivers/net/mctp/mctp-pcc.c:126:27: warning: incorrect type in assignment (different base types)
drivers/net/mctp/mctp-pcc.c:126:27: expected unsigned int [usertype] flags
drivers/net/mctp/mctp-pcc.c:126:27: got restricted __le32 [usertype]
drivers/net/mctp/mctp-pcc.c:128:28: warning: incorrect type in assignment (different base types)
drivers/net/mctp/mctp-pcc.c:128:28: expected unsigned int [usertype] length
drivers/net/mctp/mctp-pcc.c:128:28: got restricted __le32 [usertype]
Looks like struct acpi_pcct_ext_pcc_shared_memory does not specify
fields as little endian, but host endian.
You could change to endian-annotated types to those ACPI structs, but
there are probably reasons why that's not already done. This might be an
indication that there are no big-endian ACPI platforms, so you don't
need the endian conversions?
> + pcc_header = skb_push(skb, sizeof(*pcc_header));
> + pcc_header->signature = cpu_to_le32(PCC_SIGNATURE | mpnd->outbox.index);
> + pcc_header->flags = cpu_to_le32(PCC_CMD_COMPLETION_NOTIFY);
> + memcpy(&pcc_header->command, MCTP_SIGNATURE, MCTP_SIGNATURE_LENGTH);
> + pcc_header->length = cpu_to_le32(len + MCTP_SIGNATURE_LENGTH);
> +
> + if (mbox_send_message(mpnd->outbox.chan->mchan, skb) < 0) {
> + // Remove the header in case it gets sent again
> + skb_pull(skb, sizeof(*pcc_header));
> + netif_stop_queue(ndev);
> + return NETDEV_TX_BUSY;
> + }
> +
> + return NETDEV_TX_OK;
> +error:
> + dev_dstats_tx_dropped(ndev);
> + kfree_skb(skb);
> + return NETDEV_TX_OK;
> +}
> +
> +static void mctp_pcc_tx_prepare(struct mbox_client *cl, void *mssg)
> +{
> + struct mctp_pcc_ndev *mctp_pcc_ndev;
> + struct mctp_pcc_mailbox *outbox;
> + struct sk_buff *skb = mssg;
> +
> + mctp_pcc_ndev = container_of(cl, struct mctp_pcc_ndev, outbox.client);
> + outbox = &mctp_pcc_ndev->outbox;
> +
> + /* The PCC Mailbox typically does not make use of the mssg pointer
> + * The mctp-over pcc driver is the only client that uses it.
> + * This value should always be non-null; it is possible
> + * that a change in the Mailbox level will break that assumption.
> + */
> + if (!skb) {
> + WARN_ONCE(!skb, "%s called with null message.\n", __func__);
> + return;
> + }
I'd suggest netdev_warn_once(), so we know which device is causing this.
> +
> + if (skb->len > outbox->chan->shmem_size) {
> + dev_dstats_tx_dropped(mctp_pcc_ndev->ndev);
> + return;
> + }
> + memcpy_toio(outbox->chan->shmem, skb->data, skb->len);
Super minor: double space before skb->data there.
> + dev_dstats_tx_add(mctp_pcc_ndev->ndev, skb->len);
> +}
> +
> +static void mctp_pcc_tx_done(struct mbox_client *c, void *mssg, int r)
> +{
> + struct mctp_pcc_ndev *mctp_pcc_ndev;
> + struct sk_buff *skb = mssg;
> +
> + /*
> + * If there is a packet in flight during driver cleanup
> + * It may have been freed already.
> + */
> + if (!mssg)
> + return;
> + /*
> + * If the return code is non-zero, we should not report the packet
> + * as transmitted. However, we are in IRQ context right now, and we
> + * cannot safely write transmission statistics.
> + */
This reads as if you're not updating stats at all, but you do so in
mctp_pcc_tx_prepare(). I don't think this comment is necessary - if
you really want to mention this, add a comment on the
dev_dstats_tx_add() to indicate why you're calling it early.
> + mctp_pcc_ndev = container_of(c, struct mctp_pcc_ndev, outbox.client);
> + dev_consume_skb_any(skb);
> + netif_wake_queue(mctp_pcc_ndev->ndev);
> +}
> +
> +static int mctp_pcc_open(struct net_device *ndev)
> +{
> + struct mctp_pcc_ndev *mctp_pcc_ndev = netdev_priv(ndev);
> + struct mctp_pcc_mailbox *outbox, *inbox;
> +
> + outbox = &mctp_pcc_ndev->outbox;
> + inbox = &mctp_pcc_ndev->inbox;
> +
> + outbox->chan = pcc_mbox_request_channel(&outbox->client, outbox->index);
> + if (IS_ERR(outbox->chan))
> + return PTR_ERR(outbox->chan);
> +
> + if (outbox->chan->shmem_size < MCTP_PCC_MIN_SIZE) {
Minor: odd spacing here.
> + pcc_mbox_free_channel(outbox->chan);
> + return -EINVAL;
> + }
> +
> + inbox->client.rx_callback = mctp_pcc_client_rx_callback;
> + inbox->chan = pcc_mbox_request_channel(&inbox->client, inbox->index);
> + if (IS_ERR(inbox->chan)) {
> + pcc_mbox_free_channel(outbox->chan);
> + return PTR_ERR(inbox->chan);
> + }
> + if (inbox->chan->shmem_size < MCTP_PCC_MIN_SIZE) {
> + pcc_mbox_free_channel(outbox->chan);
> + pcc_mbox_free_channel(inbox->chan);
> + return -EINVAL;
> + }
> + return 0;
> +}
> +
> +static int mctp_pcc_stop(struct net_device *ndev)
> +{
> + struct mctp_pcc_ndev *mctp_pcc_ndev;
> + unsigned int count, idx;
> + struct mbox_chan *chan;
> + struct sk_buff *skb;
> +
> + mctp_pcc_ndev = netdev_priv(ndev);
> + chan = mctp_pcc_ndev->outbox.chan->mchan;
> + pcc_mbox_free_channel(mctp_pcc_ndev->inbox.chan);
> + scoped_guard(spinlock_irqsave, &chan->lock) {
> + skb = chan->active_req;
> + chan->active_req = NULL;
> + if (skb) {
> + dev_dstats_tx_dropped(ndev);
> + dev_consume_skb_any(skb);
> + }
> + while (chan->msg_count > 0) {
> + count = chan->msg_count;
> + idx = chan->msg_free;
> + if (idx >= count)
> + idx -= count;
> + else
> + idx += MBOX_TX_QUEUE_LEN - count;
> + skb = chan->msg_data[idx];
> + dev_dstats_tx_dropped(ndev);
> + dev_consume_skb_any(skb);
> + chan->msg_count--;
> + }
> + }
I'm going to assume this is all OK with respect to PCC channel activity.
> + pcc_mbox_free_channel(mctp_pcc_ndev->outbox.chan);
> + return 0;
> +}
> +
> +static int mctp_pcc_change_mtu(struct net_device *dev, int new_mtu)
> +{
> + if (new_mtu > dev->max_mtu)
> + return -EINVAL;
> + if (new_mtu < MCTP_MIN_MTU)
> + return -EINVAL;
> + return 0;
> +}
The core already does these checks, I don't think you need a
ndo_change_mtu callback at all.
Cheers,
Jeremy
next prev parent reply other threads:[~2026-05-07 3:02 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 21:43 [net-next v39] mctp pcc: Implement MCTP over PCC Transport Adam Young
2026-05-07 3:02 ` Jeremy Kerr [this message]
2026-05-07 16:00 ` Adam Young
2026-05-08 2:06 ` Jeremy Kerr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=04015745fb7223f6d7dc262ae505daf0272586fb.camel@codeconstruct.com.au \
--to=jk@codeconstruct.com.au \
--cc=Jonathan.Cameron@huawei.com \
--cc=admiyo@os.amperecomputing.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=lihuisong@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=matt@codeconstruct.com.au \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sudeep.holla@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox