netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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 v2 4/4] sfc: remove expired unicast PTP filters
Date: Wed,  1 Feb 2023 09:08:49 +0100	[thread overview]
Message-ID: <20230201080849.10482-5-ihuguet@redhat.com> (raw)
In-Reply-To: <20230201080849.10482-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 | 121 +++++++++++++++++++++------------
 1 file changed, 77 insertions(+), 44 deletions(-)

diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index a3e827cd84a8..dd46ca6c070e 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.
@@ -220,6 +223,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 {
@@ -227,6 +231,7 @@ struct efx_ptp_rxfilter {
 	__be16 ether_type;
 	__be16 loc_port;
 	__be32 loc_host[4];
+	unsigned long expiry;
 	int handle;
 };
 
@@ -1320,8 +1325,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;
 
@@ -1329,10 +1334,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 inline 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,
@@ -1341,10 +1355,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,23 +1369,24 @@ static void efx_ptp_init_filter(struct efx_nic *efx,
 			   efx_rx_queue_index(queue));
 }
 
-static int efx_ptp_insert_filter(struct efx_nic *efx,
-				 struct list_head *ptp_list,
-				 struct efx_filter_spec *spec)
+static struct efx_ptp_rxfilter *
+efx_ptp_insert_filter(struct efx_nic *efx, struct list_head *ptp_list,
+		      struct efx_filter_spec *spec)
 {
 	struct efx_ptp_rxfilter *rxfilter;
 	int rc;
 
-	if (efx_ptp_filter_exists(ptp_list, spec))
-		return 0;
+	rxfilter = efx_ptp_find_filter(ptp_list, spec);
+	if (rxfilter)
+		return rxfilter;
 
 	rc = efx_filter_insert_filter(efx, spec, true);
 	if (rc < 0)
-		return rc;
+		return ERR_PTR(rc);
 
 	rxfilter = kzalloc(sizeof(*rxfilter), GFP_KERNEL);
 	if (!rxfilter)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	rxfilter->handle = rc;
 	rxfilter->ether_type = spec->ether_type;
@@ -1382,12 +1394,12 @@ static int efx_ptp_insert_filter(struct efx_nic *efx,
 	memcpy(rxfilter->loc_host, spec->loc_host, sizeof(spec->loc_host));
 	list_add(&rxfilter->list, ptp_list);
 
-	return 0;
+	return rxfilter;
 }
 
-static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx,
-				      struct list_head *ptp_list,
-				      __be32 addr, u16 port)
+static struct efx_ptp_rxfilter *
+efx_ptp_insert_ipv4_filter(struct efx_nic *efx, struct list_head *ptp_list,
+			   __be32 addr, u16 port)
 {
 	struct efx_filter_spec spec;
 
@@ -1396,9 +1408,9 @@ static int efx_ptp_insert_ipv4_filter(struct efx_nic *efx,
 	return efx_ptp_insert_filter(efx, ptp_list, &spec);
 }
 
-static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx,
-				      struct list_head *ptp_list,
-				      struct in6_addr *addr, u16 port)
+static struct efx_ptp_rxfilter *
+efx_ptp_insert_ipv6_filter(struct efx_nic *efx, struct list_head *ptp_list,
+			   struct in6_addr *addr, u16 port)
 {
 	struct efx_filter_spec spec;
 
@@ -1407,7 +1419,8 @@ static int efx_ptp_insert_ipv6_filter(struct efx_nic *efx,
 	return efx_ptp_insert_filter(efx, ptp_list, &spec);
 }
 
-static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx)
+static struct efx_ptp_rxfilter *
+efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx)
 {
 	const u8 addr[ETH_ALEN] = PTP_ADDR_ETHER;
 	struct efx_filter_spec spec;
@@ -1422,7 +1435,7 @@ static int efx_ptp_insert_eth_multicast_filter(struct efx_nic *efx)
 static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
 {
 	struct efx_ptp_data *ptp = efx->ptp_data;
-	int rc;
+	struct efx_ptp_rxfilter *rc;
 
 	if (!ptp->channel || !list_empty(&ptp->rxfilters_mcast))
 		return 0;
@@ -1432,12 +1445,12 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
 	 */
 	rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast,
 					htonl(PTP_ADDR_IPV4), PTP_EVENT_PORT);
-	if (rc < 0)
+	if (IS_ERR(rc))
 		goto fail;
 
 	rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_mcast,
 					htonl(PTP_ADDR_IPV4), PTP_GENERAL_PORT);
-	if (rc < 0)
+	if (IS_ERR(rc))
 		goto fail;
 
 	/* if the NIC supports hw timestamps by the MAC, we can support
@@ -1448,16 +1461,16 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
 
 		rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast,
 						&ipv6_addr, PTP_EVENT_PORT);
-		if (rc < 0)
+		if (IS_ERR(rc))
 			goto fail;
 
 		rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_mcast,
 						&ipv6_addr, PTP_GENERAL_PORT);
-		if (rc < 0)
+		if (IS_ERR(rc))
 			goto fail;
 
 		rc = efx_ptp_insert_eth_multicast_filter(efx);
-		if (rc < 0)
+		if (IS_ERR(rc))
 			goto fail;
 	}
 
@@ -1465,7 +1478,7 @@ static int efx_ptp_insert_multicast_filters(struct efx_nic *efx)
 
 fail:
 	efx_ptp_remove_filters(efx, &ptp->rxfilters_mcast);
-	return rc;
+	return PTR_ERR(rc);
 }
 
 static bool efx_ptp_valid_unicast_event_pkt(struct sk_buff *skb)
@@ -1484,7 +1497,7 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx,
 					 struct sk_buff *skb)
 {
 	struct efx_ptp_data *ptp = efx->ptp_data;
-	int rc;
+	struct efx_ptp_rxfilter *rxfilter;
 
 	if (!efx_ptp_valid_unicast_event_pkt(skb))
 		return -EINVAL;
@@ -1492,28 +1505,36 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx,
 	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);
-		if (rc < 0)
+		rxfilter = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast,
+						      addr, PTP_EVENT_PORT);
+		if (IS_ERR(rxfilter))
 			goto fail;
 
-		rc = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast,
-						addr, PTP_GENERAL_PORT);
-		if (rc < 0)
+		rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES;
+
+		rxfilter = efx_ptp_insert_ipv4_filter(efx, &ptp->rxfilters_ucast,
+						      addr, PTP_GENERAL_PORT);
+		if (IS_ERR(rxfilter))
 			goto fail;
+
+		rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES;
 	} else if (efx_ptp_use_mac_tx_timestamps(efx)) {
 		/* IPv6 PTP only supported by devices with MAC hw timestamp */
 		struct in6_addr *addr = &ipv6_hdr(skb)->saddr;
 
-		rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast,
-						addr, PTP_EVENT_PORT);
-		if (rc < 0)
+		rxfilter = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast,
+						      addr, PTP_EVENT_PORT);
+		if (IS_ERR(rxfilter))
 			goto fail;
 
-		rc = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast,
-						addr, PTP_GENERAL_PORT);
-		if (rc < 0)
+		rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES;
+
+		rxfilter = efx_ptp_insert_ipv6_filter(efx, &ptp->rxfilters_ucast,
+						      addr, PTP_GENERAL_PORT);
+		if (IS_ERR(rxfilter))
 			goto fail;
+
+		rxfilter->expiry = jiffies + UCAST_FILTER_EXPIRY_JIFFIES;
 	} else {
 		return -EOPNOTSUPP;
 	}
@@ -1522,7 +1543,18 @@ static int efx_ptp_insert_unicast_filter(struct efx_nic *efx,
 
 fail:
 	efx_ptp_remove_filters(efx, &ptp->rxfilters_ucast);
-	return rc;
+	return PTR_ERR(rxfilter);
+}
+
+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)
@@ -1616,6 +1648,7 @@ static void efx_ptp_worker(struct work_struct *work)
 	}
 
 	efx_ptp_drop_time_expired_events(efx);
+	efx_ptp_drop_expired_unicast_filters(efx);
 
 	__skb_queue_head_init(&tempq);
 	efx_ptp_process_events(efx, &tempq);
-- 
2.34.3


  parent reply	other threads:[~2023-02-01  8:10 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-31 16:05 [PATCH net 0/4] sfc: support unicast PTP Íñigo Huguet
2023-01-31 16:05 ` [PATCH net 1/4] sfc: store PTP filters in a list Íñigo Huguet
2023-01-31 16:05 ` [PATCH net 2/4] sfc: allow insertion of filters for unicast PTP Íñigo Huguet
2023-01-31 16:05 ` [PATCH net 3/4] sfc: support " Íñigo Huguet
2023-01-31 16:05 ` [PATCH net 4/4] sfc: remove expired unicast PTP filters Íñigo Huguet
2023-01-31 17:46   ` kernel test robot
2023-02-01 16:09   ` kernel test robot
2023-02-01  8:08 ` [PATCH net-next v2 0/4] sfc: support unicast PTP Íñigo Huguet
2023-02-01  8:08   ` [PATCH net-next v2 1/4] sfc: store PTP filters in a list Íñigo Huguet
2023-02-02 12:13     ` Martin Habets
2023-02-01  8:08   ` [PATCH net-next v2 2/4] sfc: allow insertion of filters for unicast PTP Íñigo Huguet
2023-02-01  8:08   ` [PATCH net-next v2 3/4] sfc: support " Íñigo Huguet
2023-02-02 13:22     ` Martin Habets
2023-02-01  8:08   ` Íñigo Huguet [this message]
2023-02-02 14:12     ` [PATCH net-next v2 4/4] sfc: remove expired unicast PTP filters Martin Habets
2023-02-03 15:18       ` Íñigo Huguet
2023-02-03 15:29       ` Íñigo Huguet
2023-02-01 19:05   ` [PATCH net-next v2 0/4] sfc: support unicast PTP Jakub Kicinski
2023-02-02  7:08     ` Íñigo Huguet
2023-02-02  8:34       ` Leon Romanovsky
2023-02-02  9:17         ` Íñigo Huguet

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=20230201080849.10482-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).