From: "Íñigo Huguet" <ihuguet@redhat.com>
To: ecree.xilinx@gmail.com, habetsm.xilinx@gmail.com,
richardcochran@gmail.com
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, netdev@vger.kernel.org,
"Íñigo Huguet" <ihuguet@redhat.com>,
"Yalin Li" <yalli@redhat.com>
Subject: [PATCH net-next v3 4/4] sfc: remove expired unicast PTP filters
Date: Thu, 9 Feb 2023 11:43:49 +0100 [thread overview]
Message-ID: <20230209104349.15830-5-ihuguet@redhat.com> (raw)
In-Reply-To: <20230209104349.15830-1-ihuguet@redhat.com>
Filters inserted to support unicast PTP mode might become unused after
some time, so we need to remove them to avoid accumulating many of them.
Actually, it would be a very unusual situation that many different
addresses are used, normally only a small set of predefined
addresses are tried. Anyway, some cleanup is necessary because
maintaining old filters forever makes very little sense.
Reported-by: Yalin Li <yalli@redhat.com>
Signed-off-by: Íñigo Huguet <ihuguet@redhat.com>
---
drivers/net/ethernet/sfc/ptp.c | 83 ++++++++++++++++++++++++----------
1 file changed, 60 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 5b6ee3d23a64..b93e7220e207 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -75,6 +75,9 @@
/* How long an unmatched event or packet can be held */
#define PKT_EVENT_LIFETIME_MS 10
+/* How long unused unicast filters can be held */
+#define UCAST_FILTER_EXPIRY_JIFFIES msecs_to_jiffies(30000)
+
/* Offsets into PTP packet for identification. These offsets are from the
* start of the IP header, not the MAC header. Note that neither PTP V1 nor
* PTP V2 permit the use of IPV4 options.
@@ -218,6 +221,7 @@ struct efx_ptp_timeset {
* @ether_type: Network protocol of the filter (ETHER_P_IP / ETHER_P_IPV6)
* @loc_port: UDP port of the filter (PTP_EVENT_PORT / PTP_GENERAL_PORT)
* @loc_host: IPv4/v6 address of the filter
+ * @expiry: time when the filter expires, in jiffies
* @handle: Handle ID for the MCDI filters table
*/
struct efx_ptp_rxfilter {
@@ -225,6 +229,7 @@ struct efx_ptp_rxfilter {
__be16 ether_type;
__be16 loc_port;
__be32 loc_host[4];
+ unsigned long expiry;
int handle;
};
@@ -1318,8 +1323,8 @@ static inline void efx_ptp_process_rx(struct efx_nic *efx, struct sk_buff *skb)
local_bh_enable();
}
-static bool efx_ptp_filter_exists(struct list_head *ptp_list,
- struct efx_filter_spec *spec)
+static struct efx_ptp_rxfilter *
+efx_ptp_find_filter(struct list_head *ptp_list, struct efx_filter_spec *spec)
{
struct efx_ptp_rxfilter *rxfilter;
@@ -1327,10 +1332,19 @@ static bool efx_ptp_filter_exists(struct list_head *ptp_list,
if (rxfilter->ether_type == spec->ether_type &&
rxfilter->loc_port == spec->loc_port &&
!memcmp(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host)))
- return true;
+ return rxfilter;
}
- return false;
+ return NULL;
+}
+
+static void efx_ptp_remove_one_filter(struct efx_nic *efx,
+ struct efx_ptp_rxfilter *rxfilter)
+{
+ efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
+ rxfilter->handle);
+ list_del(&rxfilter->list);
+ kfree(rxfilter);
}
static void efx_ptp_remove_filters(struct efx_nic *efx,
@@ -1339,10 +1353,7 @@ static void efx_ptp_remove_filters(struct efx_nic *efx,
struct efx_ptp_rxfilter *rxfilter, *tmp;
list_for_each_entry_safe(rxfilter, tmp, ptp_list, list) {
- efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED,
- rxfilter->handle);
- list_del(&rxfilter->list);
- kfree(rxfilter);
+ efx_ptp_remove_one_filter(efx, rxfilter);
}
}
@@ -1358,13 +1369,17 @@ static void efx_ptp_init_filter(struct efx_nic *efx,
static int efx_ptp_insert_filter(struct efx_nic *efx,
struct list_head *ptp_list,
- struct efx_filter_spec *spec)
+ struct efx_filter_spec *spec,
+ unsigned long expiry)
{
struct efx_ptp_rxfilter *rxfilter;
int rc;
- if (efx_ptp_filter_exists(ptp_list, spec))
+ rxfilter = efx_ptp_find_filter(ptp_list, spec);
+ if (rxfilter) {
+ rxfilter->expiry = expiry;
return 0;
+ }
rc = efx_filter_insert_filter(efx, spec, true);
if (rc < 0)
@@ -1378,6 +1393,7 @@ static int efx_ptp_insert_filter(struct efx_nic *efx,
rxfilter->ether_type = spec->ether_type;
rxfilter->loc_port = spec->loc_port;
memcpy(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host));
+ rxfilter->expiry = expiry;
list_add(&rxfilter->list, ptp_list);
return 0;
@@ -1385,28 +1401,31 @@ static int efx_ptp_insert_filter(struct efx_nic *efx,
static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx,
struct list_head *ptp_list,
- __be32 addr, u16 port)
+ __be32 addr, u16 port,
+ unsigned long expiry)
{
struct efx_filter_spec spec;
efx_ptp_init_filter(efx, &spec);
efx_filter_set_ipv4_local(&spec, IPPROTO_UDP, addr, htons(port));
- return efx_ptp_insert_filter(efx, ptp_list, &spec);
+ return efx_ptp_insert_filter(efx, ptp_list, &spec, expiry);
}
static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx,
struct list_head *ptp_list,
- struct in6_addr *addr, u16 port)
+ struct in6_addr *addr, u16 port,
+ unsigned long expiry)
{
struct efx_filter_spec spec;
efx_ptp_init_filter(efx, &spec);
efx_filter_set_ipv6_local(&spec, IPPROTO_UDP, addr, htons(port));
- return efx_ptp_insert_filter(efx, ptp_list, &spec);
+ return efx_ptp_insert_filter(efx, ptp_list, &spec, expiry);
}
static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx)
{
+ struct efx_ptp_data *ptp = efx->ptp_data;
const u8 addr[ETH_ALEN] = PTP_ADDR_ETHER;
struct efx_filter_spec spec;
@@ -1414,7 +1433,7 @@ static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx)
efx_filter_set_eth_local(&spec, EFX_FILTER_VID_UNSPEC, addr);
spec.match_flags |= EFX_FILTER_MATCH_ETHER_TYPE;
spec.ether_type = htons(ETH_P_1588);
- return efx_ptp_insert_filter(efx, &efx->ptp_data->rxfilters_mcast, &spec);
+ return efx_ptp_insert_filter(efx, &ptp->rxfilters_mcast, &spec, 0);
}
static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
@@ -1429,12 +1448,14 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
* that there is no packet re-ordering.
*/
rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast,
- htonl(PTP_ADDR_IPV4), PTP_EVENT_PORT);
+ htonl(PTP_ADDR_IPV4), PTP_EVENT_PORT,
+ 0);
if (rc < 0)
goto fail;
rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast,
- htonl(PTP_ADDR_IPV4), PTP_GENERAL_PORT);
+ htonl(PTP_ADDR_IPV4), PTP_GENERAL_PORT,
+ 0);
if (rc < 0)
goto fail;
@@ -1445,12 +1466,12 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
struct in6_addr ipv6_addr = {{PTP_ADDR_IPV6}};
rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast,
- &ipv6_addr, PTP_EVENT_PORT);
+ &ipv6_addr, PTP_EVENT_PORT, 0);
if (rc < 0)
goto fail;
rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast,
- &ipv6_addr, PTP_GENERAL_PORT);
+ &ipv6_addr, PTP_GENERAL_PORT, 0);
if (rc < 0)
goto fail;
@@ -1486,21 +1507,24 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx,
struct sk_buff *skb)
{
struct efx_ptp_data *ptp = efx->ptp_data;
+ unsigned long expiry;
int rc;
if (!efx_ptp_valid_unicast_event_pkt(skb))
return -EINVAL;
+ expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES;
+
if (skb->protocol == htons(ETH_P_IP)) {
__be32 addr = ip_hdr(skb)->saddr;
rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast,
- addr, PTP_EVENT_PORT);
+ addr, PTP_EVENT_PORT, expiry);
if (rc < 0)
goto fail;
rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast,
- addr, PTP_GENERAL_PORT);
+ addr, PTP_GENERAL_PORT, expiry);
if (rc < 0)
goto fail;
} else if (efx_ptp_use_mac_tx_timestamps(efx)) {
@@ -1508,12 +1532,12 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx,
struct in6_addr *addr = &ipv6_hdr(skb)->saddr;
rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast,
- addr, PTP_EVENT_PORT);
+ addr, PTP_EVENT_PORT, expiry);
if (rc < 0)
goto fail;
rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast,
- addr, PTP_GENERAL_PORT);
+ addr, PTP_GENERAL_PORT, expiry);
if (rc < 0)
goto fail;
} else {
@@ -1527,6 +1551,17 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx,
return rc;
}
+static void efx_ptp_drop_expired_unicast_filters(struct efx_nic *efx)
+{
+ struct efx_ptp_data *ptp = efx->ptp_data;
+ struct efx_ptp_rxfilter *rxfilter, *tmp;
+
+ list_for_each_entry_safe(rxfilter, tmp, &ptp->rxfilters_ucast, list) {
+ if (time_is_before_jiffies(rxfilter->expiry))
+ efx_ptp_remove_one_filter(efx, rxfilter);
+ }
+}
+
static int efx_ptp_start(struct efx_nic *efx)
{
struct efx_ptp_data *ptp = efx->ptp_data;
@@ -1627,6 +1662,8 @@ static void efx_ptp_worker(struct work_struct *work)
while ((skb = __skb_dequeue(&tempq)))
efx_ptp_process_rx(efx, skb);
+
+ efx_ptp_drop_expired_unicast_filters(efx);
}
static const struct ptp_clock_info efx_phc_clock_info = {
--
2.34.3
prev parent reply other threads:[~2023-02-09 10:46 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-09 10:43 [PATCH net-next v3 0/4] sfc: support unicast PTP Íñigo Huguet
2023-02-09 10:43 ` [PATCH net-next v3 1/4] sfc: store PTP filters in a list Íñigo Huguet
2023-02-14 16:08 ` Edward Cree
2023-02-09 10:43 ` [PATCH net-next v3 2/4] sfc: allow insertion of filters for unicast PTP Íñigo Huguet
2023-02-09 10:43 ` [PATCH net-next v3 3/4] sfc: support " Íñigo Huguet
2023-02-09 10:43 ` Íñigo Huguet [this message]
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=20230209104349.15830-5-ihuguet@redhat.com \
--to=ihuguet@redhat.com \
--cc=davem@davemloft.net \
--cc=ecree.xilinx@gmail.com \
--cc=edumazet@google.com \
--cc=habetsm.xilinx@gmail.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=richardcochran@gmail.com \
--cc=yalli@redhat.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;
as well as URLs for NNTP newsgroup(s).