From: Zinc Lim <limzhineng2@gmail.com>
To: alexanderduyck@fb.com, kuba@kernel.org, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@kernel.org, pabeni@redhat.com,
linux@roeck-us.net, horms@kernel.org, hmohsin@meta.com,
mike.marciniszyn@gmail.com
Cc: kernel-team@meta.com, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-hwmon@vger.kernel.org,
zinclim@meta.com, limzhineng2@gmail.com
Subject: [PATCH net-next v4 2/6] eth: fbnic: cache hwmon sensor readings
Date: Wed, 14 Oct 2026 15:22:20 -0700 [thread overview]
Message-ID: <20261014222225.2803660-3-limzhineng2@gmail.com> (raw)
In-Reply-To: <20261014222225.2803660-1-limzhineng2@gmail.com>
Each hwmon attribute access triggers its own TSENE firmware mailbox
round-trip, so reading the full set of attributes or polling them at a
high rate floods the firmware mailbox with quick, successive IPC messages
for data that barely changes between ticks.
Cache the last temperature and voltage reading and serve reads from it
for the remainder of the current jiffy. A single TSENE response carries
both readings, so one transaction on a miss refreshes both and satisfies
a whole batch of reads. The cache is seeded with the FBNIC_SENSOR_NO_DATA
sentinel in fbnic_mbx_init() so the first read always refreshes.
Signed-off-by: Zinc Lim <limzhineng2@gmail.com>
---
drivers/net/ethernet/meta/fbnic/fbnic.h | 7 +++++
drivers/net/ethernet/meta/fbnic/fbnic_fw.c | 7 +++++
drivers/net/ethernet/meta/fbnic/fbnic_fw.h | 7 +++++
drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c | 31 +++++++++++++------
4 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic.h b/drivers/net/ethernet/meta/fbnic/fbnic.h
index 1f9fbd71447f..857a64b518f3 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic.h
@@ -22,11 +22,18 @@ struct fbnic_napi_vector;
#define FBNIC_MAX_NAPI_VECTORS 128u
#define FBNIC_MBX_CMPL_SLOTS 4
+struct fbnic_hwmon_cache {
+ unsigned long last_read;
+ s32 temp_mdeg;
+ s32 volt_mv;
+};
+
struct fbnic_dev {
struct device *dev;
struct net_device *netdev;
struct dentry *dbg_fbd;
struct device *hwmon;
+ struct fbnic_hwmon_cache hwmon_cache;
struct devlink_health_reporter *fw_reporter;
struct devlink_health_reporter *otp_reporter;
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 49b8813a3564..82307f212f58 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -105,6 +105,13 @@ void fbnic_mbx_init(struct fbnic_dev *fbd)
/* Reset FW Capabilities */
memset(&fbd->fw_cap, 0, sizeof(fbd->fw_cap));
+ /* Seed cache with sentinel so the first read always refreshes. The
+ * cache mirrors what firmware reported, so drop it when the mailbox
+ * restarts.
+ */
+ fbd->hwmon_cache.temp_mdeg = FBNIC_SENSOR_NO_DATA;
+ fbd->hwmon_cache.volt_mv = FBNIC_SENSOR_NO_DATA;
+
/* Reinitialize mailbox memory */
for (i = 0; i < FBNIC_IPC_MBX_INDICES; i++)
memset(&fbd->mbx[i], 0, sizeof(struct fbnic_fw_mbx));
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
index f47669129c9d..ddedb7c0e0a7 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.h
@@ -6,6 +6,7 @@
#include <linux/completion.h>
#include <linux/if_ether.h>
+#include <linux/limits.h>
#include <linux/types.h>
struct fbnic_dev;
@@ -59,6 +60,12 @@ enum {
(BIT(FBNIC_FW_CAP_F_BMC_TCAM_REINIT) | \
BIT(FBNIC_FW_CAP_F_BMC_MACDA_SYNC))
+/* Sentinel for a sensor value the driver does not have: a threshold the
+ * firmware never populated (older firmware) or a cache entry not yet
+ * refreshed.
+ */
+#define FBNIC_SENSOR_NO_DATA S32_MIN
+
struct fbnic_fw_cap {
unsigned long state;
struct {
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c b/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c
index 6c8c66ab86c1..0c3fe2a37227 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_hwmon.c
@@ -2,6 +2,7 @@
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
#include <linux/hwmon.h>
+#include <linux/jiffies.h>
#include "fbnic.h"
#include "fbnic_mac.h"
@@ -30,26 +31,31 @@ static umode_t fbnic_hwmon_is_visible(const void *drvdata,
static int fbnic_hwmon_sensor_read(struct fbnic_dev *fbd, int id, long *val)
{
+ struct fbnic_hwmon_cache *cache = &fbd->hwmon_cache;
struct fbnic_fw_completion *fw_cmpl;
int err = 0;
- s32 *sensor;
-
- fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);
- if (!fw_cmpl)
- return -ENOMEM;
+ s32 *cached;
switch (id) {
case FBNIC_SENSOR_TEMP:
- sensor = &fw_cmpl->u.tsene.millidegrees;
+ cached = &cache->temp_mdeg;
break;
case FBNIC_SENSOR_VOLTAGE:
- sensor = &fw_cmpl->u.tsene.millivolts;
+ cached = &cache->volt_mv;
break;
default:
- err = -EINVAL;
- goto exit_free;
+ return -EINVAL;
+ }
+
+ if (*cached != FBNIC_SENSOR_NO_DATA && cache->last_read == jiffies) {
+ *val = *cached;
+ return 0;
}
+ fw_cmpl = fbnic_fw_alloc_cmpl(FBNIC_TLV_MSG_ID_TSENE_READ_RESP);
+ if (!fw_cmpl)
+ return -ENOMEM;
+
err = fbnic_fw_xmit_tsene_read_msg(fbd, fw_cmpl);
if (err) {
dev_err(fbd->dev,
@@ -72,7 +78,12 @@ static int fbnic_hwmon_sensor_read(struct fbnic_dev *fbd, int id, long *val)
goto exit_cleanup;
}
- *val = *sensor;
+ /* FW returns both readings in one response, cache both. */
+ cache->temp_mdeg = fw_cmpl->u.tsene.millidegrees;
+ cache->volt_mv = fw_cmpl->u.tsene.millivolts;
+ cache->last_read = jiffies;
+
+ *val = *cached;
exit_cleanup:
fbnic_mbx_clear_cmpl(fbd, fw_cmpl);
exit_free:
--
2.53.0-Meta
next prev parent reply other threads:[~2026-10-14 22:22 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-14 22:22 [PATCH net-next v4 0/6] eth: fbnic: expand hwmon sensor support Zinc Lim
2026-10-14 22:22 ` [PATCH net-next v4 1/6] eth: fbnic: move sensor read logic out of fbnic_mac Zinc Lim
2026-10-14 22:22 ` Zinc Lim [this message]
2026-10-14 22:22 ` [PATCH net-next v4 3/6] eth: fbnic: report temperature and voltage thresholds via hwmon Zinc Lim
2026-10-14 22:22 ` [PATCH net-next v4 4/6] eth: fbnic: parse the alarm range reported by firmware Zinc Lim
2026-10-14 22:22 ` [PATCH net-next v4 5/6] eth: fbnic: report temperature and voltage alarms via hwmon Zinc Lim
2026-10-14 22:22 ` [PATCH net-next v4 6/6] eth: fbnic: derive the alarm range on older firmware Zinc Lim
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=20261014222225.2803660-3-limzhineng2@gmail.com \
--to=limzhineng2@gmail.com \
--cc=alexanderduyck@fb.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=hmohsin@meta.com \
--cc=horms@kernel.org \
--cc=kernel-team@meta.com \
--cc=kuba@kernel.org \
--cc=linux-hwmon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=mike.marciniszyn@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=zinclim@meta.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