Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] net: qrtr: ns: Limit the maximum server registration per node
From: Simon Horman @ 2026-03-27  9:58 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: davem, edumazet, kuba, pabeni, linux-arm-msm, netdev,
	linux-kernel, andersson, yimingqian591, chris.lew, mani, stable
In-Reply-To: <20260325104415.104972-2-manivannan.sadhasivam@oss.qualcomm.com>

On Wed, Mar 25, 2026 at 04:14:14PM +0530, Manivannan Sadhasivam wrote:
> Current code does no bound checking on the number of servers added per
> node. A malicious client can flood NEW_SERVER messages and exhaust memory.
> 
> Fix this issue by limiting the maximum number of server registrations to
> 256 per node. If the NEW_SERVER message is received for an old port, then
> don't restrict it as it will get replaced.
> 
> Note that the limit of 256 is chosen based on the current platform
> requirements. If requirement changes in the future, this limit can be
> increased.
> 
> Cc: stable@vger.kernel.org
> Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace")
> Reported-by: Yiming Qian <yimingqian591@gmail.com>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>

Reviewed-by: Simon Horman <horms@kernel.org>

> ---
>  net/qrtr/ns.c | 24 ++++++++++++++++++++----
>  1 file changed, 20 insertions(+), 4 deletions(-)
> 
> diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
> index 3203b2220860..fb4e8a2d370d 100644
> --- a/net/qrtr/ns.c
> +++ b/net/qrtr/ns.c
> @@ -67,8 +67,14 @@ struct qrtr_server {
>  struct qrtr_node {
>  	unsigned int id;
>  	struct xarray servers;
> +	u32 server_count;
>  };
>  
> +/* Max server limit is chosen based on the current platform requirements. If the
> + * requirement changes in the future, this value can be increased.
> + */
> +#define QRTR_NS_MAX_SERVERS 256
> +
>  static struct qrtr_node *node_get(unsigned int node_id)
>  {
>  	struct qrtr_node *node;
> @@ -229,6 +235,17 @@ static struct qrtr_server *server_add(unsigned int service,
>  	if (!service || !port)
>  		return NULL;
>  
> +	node = node_get(node_id);
> +	if (!node)
> +		return NULL;

This is not new behaviour added by patch, but If I understand things
correctly, node_get will allocate a new node if one doesn't already exist
for the node_id.

I am wondering if any bounds are placed on the number of nodes that can be
created. And, if not, is this a point of concern from a memory exhaustion
perspective?

...

^ permalink raw reply

* Re: [PATCH net-next 1/5] dpll: zl3073x: clean up esync get/set and use zl3073x_out_is_ndiv()
From: Petr Oros @ 2026-03-27 10:03 UTC (permalink / raw)
  To: Ivan Vecera, netdev
  Cc: Arkadiusz Kubalewski, Jiri Pirko, Michal Schmidt, Prathosh Satish,
	Simon Horman, Vadim Fedorenko, linux-kernel, Conor Dooley,
	Krzysztof Kozlowski, Rob Herring, devicetree, Pasi Vaananen
In-Reply-To: <20260319174826.7623-2-ivecera@redhat.com>

> Return -EOPNOTSUPP early in esync_get callbacks when esync is not
> supported instead of conditionally populating the range at the end.
> This simplifies the control flow by removing the finish label/goto
> in the output variant and the conditional range assignment in both
> input and output variants.
>
> Replace open-coded N-div signal format switch statements with
> zl3073x_out_is_ndiv() helper in esync_get, esync_set and
> frequency_set callbacks.
>
> Signed-off-by: Ivan Vecera <ivecera@redhat.com>
> ---
>   drivers/dpll/zl3073x/dpll.c | 64 ++++++++++++-------------------------
>   1 file changed, 20 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
> index a29f606318f6d..79ef62d69a32d 100644
> --- a/drivers/dpll/zl3073x/dpll.c
> +++ b/drivers/dpll/zl3073x/dpll.c
> @@ -131,6 +131,12 @@ zl3073x_dpll_input_pin_esync_get(const struct dpll_pin *dpll_pin,
>   	ref_id = zl3073x_input_pin_ref_get(pin->id);
>   	ref = zl3073x_ref_state_get(zldev, ref_id);
>   
> +	if (!pin->esync_control || zl3073x_ref_freq_get(ref) == 1)
> +		return -EOPNOTSUPP;
> +
> +	esync->range = esync_freq_ranges;
> +	esync->range_num = ARRAY_SIZE(esync_freq_ranges);
> +
>   	switch (FIELD_GET(ZL_REF_SYNC_CTRL_MODE, ref->sync_ctrl)) {
>   	case ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75:
>   		esync->freq = ref->esync_n_div == ZL_REF_ESYNC_DIV_1HZ ? 1 : 0;
> @@ -142,17 +148,6 @@ zl3073x_dpll_input_pin_esync_get(const struct dpll_pin *dpll_pin,
>   		break;
>   	}
>   
> -	/* If the pin supports esync control expose its range but only
> -	 * if the current reference frequency is > 1 Hz.
> -	 */
> -	if (pin->esync_control && zl3073x_ref_freq_get(ref) > 1) {
> -		esync->range = esync_freq_ranges;
> -		esync->range_num = ARRAY_SIZE(esync_freq_ranges);
> -	} else {
> -		esync->range = NULL;
> -		esync->range_num = 0;
> -	}
> -
>   	return 0;
>   }
>   
> @@ -582,8 +577,8 @@ zl3073x_dpll_output_pin_esync_get(const struct dpll_pin *dpll_pin,
>   	struct zl3073x_dpll_pin *pin = pin_priv;
>   	const struct zl3073x_synth *synth;
>   	const struct zl3073x_out *out;
> +	u32 synth_freq, out_freq;
>   	u8 clock_type, out_id;
> -	u32 synth_freq;
>   
>   	out_id = zl3073x_output_pin_out_get(pin->id);
>   	out = zl3073x_out_state_get(zldev, out_id);
> @@ -592,17 +587,19 @@ zl3073x_dpll_output_pin_esync_get(const struct dpll_pin *dpll_pin,
>   	 * for N-division is also used for the esync divider so both cannot
>   	 * be used.
>   	 */
> -	switch (zl3073x_out_signal_format_get(out)) {
> -	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV:
> -	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV:
> +	if (zl3073x_out_is_ndiv(out))
>   		return -EOPNOTSUPP;
> -	default:
> -		break;
> -	}
>   
>   	/* Get attached synth frequency */
>   	synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out));
>   	synth_freq = zl3073x_synth_freq_get(synth);
> +	out_freq = synth_freq / out->div;
> +
> +	if (!pin->esync_control || out_freq == 1)
> +		return -EOPNOTSUPP;
> +
> +	esync->range = esync_freq_ranges;
> +	esync->range_num = ARRAY_SIZE(esync_freq_ranges);
>   
>   	clock_type = FIELD_GET(ZL_OUTPUT_MODE_CLOCK_TYPE, out->mode);
>   	if (clock_type != ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC) {
> @@ -610,11 +607,11 @@ zl3073x_dpll_output_pin_esync_get(const struct dpll_pin *dpll_pin,
>   		esync->freq = 0;
>   		esync->pulse = 0;
>   
> -		goto finish;
> +		return 0;
>   	}
>   
>   	/* Compute esync frequency */
> -	esync->freq = synth_freq / out->div / out->esync_n_period;
> +	esync->freq = out_freq / out->esync_n_period;
>   
>   	/* By comparing the esync_pulse_width to the half of the pulse width
>   	 * the esync pulse percentage can be determined.
> @@ -623,18 +620,6 @@ zl3073x_dpll_output_pin_esync_get(const struct dpll_pin *dpll_pin,
>   	 */
>   	esync->pulse = (50 * out->esync_n_width) / out->div;
>   
> -finish:
> -	/* Set supported esync ranges if the pin supports esync control and
> -	 * if the output frequency is > 1 Hz.
> -	 */
> -	if (pin->esync_control && (synth_freq / out->div) > 1) {
> -		esync->range = esync_freq_ranges;
> -		esync->range_num = ARRAY_SIZE(esync_freq_ranges);
> -	} else {
> -		esync->range = NULL;
> -		esync->range_num = 0;
> -	}
> -
>   	return 0;
>   }
>   
> @@ -660,13 +645,8 @@ zl3073x_dpll_output_pin_esync_set(const struct dpll_pin *dpll_pin,
>   	 * for N-division is also used for the esync divider so both cannot
>   	 * be used.
>   	 */
> -	switch (zl3073x_out_signal_format_get(&out)) {
> -	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV:
> -	case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV:
> +	if (zl3073x_out_is_ndiv(&out))
>   		return -EOPNOTSUPP;
> -	default:
> -		break;
> -	}
>   
>   	/* Select clock type */
>   	if (freq)
> @@ -728,9 +708,9 @@ zl3073x_dpll_output_pin_frequency_set(const struct dpll_pin *dpll_pin,
>   	struct zl3073x_dev *zldev = zldpll->dev;
>   	struct zl3073x_dpll_pin *pin = pin_priv;
>   	const struct zl3073x_synth *synth;
> -	u8 out_id, signal_format;
>   	u32 new_div, synth_freq;
>   	struct zl3073x_out out;
> +	u8 out_id;
>   
>   	out_id = zl3073x_output_pin_out_get(pin->id);
>   	out = *zl3073x_out_state_get(zldev, out_id);
> @@ -740,12 +720,8 @@ zl3073x_dpll_output_pin_frequency_set(const struct dpll_pin *dpll_pin,
>   	synth_freq = zl3073x_synth_freq_get(synth);
>   	new_div = synth_freq / (u32)frequency;
>   
> -	/* Get used signal format for the given output */
> -	signal_format = zl3073x_out_signal_format_get(&out);
> -
>   	/* Check signal format */
> -	if (signal_format != ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV &&
> -	    signal_format != ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV) {
> +	if (!zl3073x_out_is_ndiv(&out)) {
>   		/* For non N-divided signal formats the frequency is computed
>   		 * as division of synth frequency and output divisor.
>   		 */

LGTM,

Reviewed-by: Petr Oros <poros@redhat.com>



^ permalink raw reply

* Re: [PATCH 2/2] net: qrtr: ns: Limit the maximum lookups per socket
From: Simon Horman @ 2026-03-27 10:07 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: davem, edumazet, kuba, pabeni, linux-arm-msm, netdev,
	linux-kernel, andersson, yimingqian591, chris.lew, mani, stable
In-Reply-To: <20260325104415.104972-3-manivannan.sadhasivam@oss.qualcomm.com>

On Wed, Mar 25, 2026 at 04:14:15PM +0530, Manivannan Sadhasivam wrote:
> Current code does no bound checking on the number of lookups a client can
> perform per socket. Though the code restricts the lookups to local clients,
> there is still a possibility of a malicious local client sending a flood of
> NEW_LOOKUP messages over the same socket.
> 
> Fix this issue by limiting the maximum number of lookups to 64 per socket.
> Note that, limit of 64 is chosen based on the current platform
> requirements. If requirement changes in the future, this limit can be
> increased.
> 
> Cc: stable@vger.kernel.org
> Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace")
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> ---
>  net/qrtr/ns.c | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
> index fb4e8a2d370d..707fde809939 100644
> --- a/net/qrtr/ns.c
> +++ b/net/qrtr/ns.c
> @@ -70,10 +70,11 @@ struct qrtr_node {
>  	u32 server_count;
>  };
>  
> -/* Max server limit is chosen based on the current platform requirements. If the
> - * requirement changes in the future, this value can be increased.
> +/* Max server, lookup limits are chosen based on the current platform requirements.
> + * If the requirement changes in the future, these values can be increased.
>   */
>  #define QRTR_NS_MAX_SERVERS 256
> +#define QRTR_NS_MAX_LOOKUPS 64
>  
>  static struct qrtr_node *node_get(unsigned int node_id)
>  {
> @@ -545,11 +546,24 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
>  	struct qrtr_node *node;
>  	unsigned long node_idx;
>  	unsigned long srv_idx;
> +	u8 count = 0;
>  
>  	/* Accept only local observers */
>  	if (from->sq_node != qrtr_ns.local_node)
>  		return -EINVAL;
>  
> +	/* Make sure the client performs only maximum allowed lookups */
> +	list_for_each_entry(lookup, &qrtr_ns.lookups, li) {
> +		if (lookup->sq.sq_node == from->sq_node &&
> +		    lookup->sq.sq_port == from->sq_port)
> +			count++;

This feels like it could get quite expensive.
If many lookups are added, it feels like it may be O(n^2).

Is this something that has been considered?

> +	}
> +
> +	if (count >= QRTR_NS_MAX_LOOKUPS) {
> +		pr_err_ratelimited("QRTR client node exceeds max lookup limit!\n");
> +		return -ENOSPC;
> +	}
> +
>  	lookup = kzalloc_obj(*lookup);
>  	if (!lookup)
>  		return -ENOMEM;
> -- 
> 2.51.0
> 

^ permalink raw reply

* Re: [PATCH 1/2] net: qrtr: ns: Limit the maximum server registration per node
From: Manivannan Sadhasivam @ 2026-03-27 10:10 UTC (permalink / raw)
  To: Simon Horman
  Cc: Manivannan Sadhasivam, davem, edumazet, kuba, pabeni,
	linux-arm-msm, netdev, linux-kernel, andersson, yimingqian591,
	chris.lew, stable
In-Reply-To: <20260327095832.GC111839@horms.kernel.org>

On Fri, Mar 27, 2026 at 09:58:32AM +0000, Simon Horman wrote:
> On Wed, Mar 25, 2026 at 04:14:14PM +0530, Manivannan Sadhasivam wrote:
> > Current code does no bound checking on the number of servers added per
> > node. A malicious client can flood NEW_SERVER messages and exhaust memory.
> > 
> > Fix this issue by limiting the maximum number of server registrations to
> > 256 per node. If the NEW_SERVER message is received for an old port, then
> > don't restrict it as it will get replaced.
> > 
> > Note that the limit of 256 is chosen based on the current platform
> > requirements. If requirement changes in the future, this limit can be
> > increased.
> > 
> > Cc: stable@vger.kernel.org
> > Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace")
> > Reported-by: Yiming Qian <yimingqian591@gmail.com>
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> 
> Reviewed-by: Simon Horman <horms@kernel.org>
> 
> > ---
> >  net/qrtr/ns.c | 24 ++++++++++++++++++++----
> >  1 file changed, 20 insertions(+), 4 deletions(-)
> > 
> > diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
> > index 3203b2220860..fb4e8a2d370d 100644
> > --- a/net/qrtr/ns.c
> > +++ b/net/qrtr/ns.c
> > @@ -67,8 +67,14 @@ struct qrtr_server {
> >  struct qrtr_node {
> >  	unsigned int id;
> >  	struct xarray servers;
> > +	u32 server_count;
> >  };
> >  
> > +/* Max server limit is chosen based on the current platform requirements. If the
> > + * requirement changes in the future, this value can be increased.
> > + */
> > +#define QRTR_NS_MAX_SERVERS 256
> > +
> >  static struct qrtr_node *node_get(unsigned int node_id)
> >  {
> >  	struct qrtr_node *node;
> > @@ -229,6 +235,17 @@ static struct qrtr_server *server_add(unsigned int service,
> >  	if (!service || !port)
> >  		return NULL;
> >  
> > +	node = node_get(node_id);
> > +	if (!node)
> > +		return NULL;
> 
> This is not new behaviour added by patch, but If I understand things
> correctly, node_get will allocate a new node if one doesn't already exist
> for the node_id.
> 

Yes!

> I am wondering if any bounds are placed on the number of nodes that can be
> created. And, if not, is this a point of concern from a memory exhaustion
> perspective?
> 

That's true. I plan to send a followup for that. This series just limits the
scope in addressing the reported issue.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply

* Re: [PATCH iwl-next v1] ixgbe: fix eeprom_id staleness and non-fatal EMPR reload failure
From: Simon Horman @ 2026-03-27 10:10 UTC (permalink / raw)
  To: Aleksandr Loktionov; +Cc: intel-wired-lan, anthony.l.nguyen, netdev
In-Reply-To: <20260320051455.427282-1-aleksandr.loktionov@intel.com>

On Fri, Mar 20, 2026 at 06:14:54AM +0100, Aleksandr Loktionov wrote:
> Three related bugs around FW version reporting after EMPR reset on E610:
> 
> 1. ixgbe_refresh_fw_version() silently discarded the error return from
>    ixgbe_get_flash_data(), so a failed NVM re-read left adapter->eeprom_id
>    with whatever stale data it held before the reset.  Propagate the error
>    and set eeprom_id to "unknown" on failure so that ethtool -i and
>    devlink dev info never show a version that no longer reflects reality.
> 
> 2. ixgbe_devlink_reload_empr_finish() returned 0 without ever refreshing
>    the FW version after the EMPR completed.  Add the refresh call, but
>    treat it as best-effort: a failure to re-read flash does not mean the
>    EMPR itself failed.  Log a netdev_warn() and return 0 so devlink
>    reports the correct reload outcome.
> 
> 3. ixgbe_reinit_locked() never refreshed the FW version for E610.
>    Because E610 has no FW event that notifies peer PFs when an EMPR
>    triggered by another PF's devlink reload completes, any PF that
>    subsequently goes through reinit would keep stale data in hw->flash
>    and adapter->eeprom_id.  Add the same best-effort refresh here,
>    gated on ixgbe_mac_e610, with a netdev_warn() on failure.
> 
> Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

Reviewed-by: Simon Horman <horms@kernel.org>

...

> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> index 56aabaa..40d593b 100644
> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
> @@ -1155,12 +1155,30 @@ static int ixgbe_set_eeprom(struct net_device *netdev,
>  	return ret_val;
>  }
>  
> -void ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter)
> +/**
> + * ixgbe_refresh_fw_version - re-read flash data and update eeprom_id cache
> + * @adapter: board private structure
> + *
> + * Re-reads the NVM/flash and refreshes the cached adapter->eeprom_id string.
> + * On failure the cache is set to "unknown" so that ethtool -i never shows a
> + * stale version string after a failed reset.
> + *
> + * Return: 0 on success, negative error code on failure.
> + */
> +int ixgbe_refresh_fw_version(struct ixgbe_adapter *adapter)
>  {
>  	struct ixgbe_hw *hw = &adapter->hw;
> +	int err;
> +
> +	err = ixgbe_get_flash_data(hw);
> +	if (err) {
> +		strscpy(adapter->eeprom_id, "unknown",
> +			sizeof(adapter->eeprom_id));

nit: I think you can omit the size argument to strscpy
     because eeprom_id is an array.

> +		return err;
> +	}
>  
> -	ixgbe_get_flash_data(hw);
>  	ixgbe_set_fw_version_e610(adapter);
> +	return 0;
>  }
>  
>  static void ixgbe_get_drvinfo(struct net_device *netdev,

...

^ permalink raw reply

* Re: [PATCH net-next 2/5] dpll: zl3073x: use FIELD_MODIFY() for clear-and-set patterns
From: Petr Oros @ 2026-03-27 10:11 UTC (permalink / raw)
  To: Ivan Vecera, netdev
  Cc: Arkadiusz Kubalewski, Jiri Pirko, Michal Schmidt, Prathosh Satish,
	Simon Horman, Vadim Fedorenko, linux-kernel, Conor Dooley,
	Krzysztof Kozlowski, Rob Herring, devicetree, Pasi Vaananen
In-Reply-To: <20260319174826.7623-3-ivecera@redhat.com>

> Replace open-coded clear-and-set bitfield operations with
> FIELD_MODIFY().
>
> Signed-off-by: Ivan Vecera <ivecera@redhat.com>
> ---
>   drivers/dpll/zl3073x/chan.h  | 17 ++++++-----------
>   drivers/dpll/zl3073x/core.c  |  3 +--
>   drivers/dpll/zl3073x/flash.c |  3 +--
>   3 files changed, 8 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/dpll/zl3073x/chan.h b/drivers/dpll/zl3073x/chan.h
> index e0f02d3432086..481da2133202b 100644
> --- a/drivers/dpll/zl3073x/chan.h
> +++ b/drivers/dpll/zl3073x/chan.h
> @@ -66,8 +66,7 @@ static inline u8 zl3073x_chan_ref_get(const struct zl3073x_chan *chan)
>    */
>   static inline void zl3073x_chan_mode_set(struct zl3073x_chan *chan, u8 mode)
>   {
> -	chan->mode_refsel &= ~ZL_DPLL_MODE_REFSEL_MODE;
> -	chan->mode_refsel |= FIELD_PREP(ZL_DPLL_MODE_REFSEL_MODE, mode);
> +	FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_MODE, &chan->mode_refsel, mode);
>   }
>   
>   /**
> @@ -77,8 +76,7 @@ static inline void zl3073x_chan_mode_set(struct zl3073x_chan *chan, u8 mode)
>    */
>   static inline void zl3073x_chan_ref_set(struct zl3073x_chan *chan, u8 ref)
>   {
> -	chan->mode_refsel &= ~ZL_DPLL_MODE_REFSEL_REF;
> -	chan->mode_refsel |= FIELD_PREP(ZL_DPLL_MODE_REFSEL_REF, ref);
> +	FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_REF, &chan->mode_refsel, ref);
>   }
>   
>   /**
> @@ -110,13 +108,10 @@ zl3073x_chan_ref_prio_set(struct zl3073x_chan *chan, u8 ref, u8 prio)
>   {
>   	u8 *val = &chan->ref_prio[ref / 2];
>   
> -	if (!(ref & 1)) {
> -		*val &= ~ZL_DPLL_REF_PRIO_REF_P;
> -		*val |= FIELD_PREP(ZL_DPLL_REF_PRIO_REF_P, prio);
> -	} else {
> -		*val &= ~ZL_DPLL_REF_PRIO_REF_N;
> -		*val |= FIELD_PREP(ZL_DPLL_REF_PRIO_REF_N, prio);
> -	}
> +	if (!(ref & 1))
> +		FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_P, val, prio);
> +	else
> +		FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_N, val, prio);
>   }
>   
>   /**
> diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c
> index 6363002d48d46..7eebfc1ad1019 100644
> --- a/drivers/dpll/zl3073x/core.c
> +++ b/drivers/dpll/zl3073x/core.c
> @@ -743,8 +743,7 @@ int zl3073x_dev_phase_avg_factor_set(struct zl3073x_dev *zldev, u8 factor)
>   	value = (factor + 1) & 0x0f;
>   
>   	/* Update phase measurement control register */
> -	dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR;
> -	dpll_meas_ctrl |= FIELD_PREP(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, value);
> +	FIELD_MODIFY(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, &dpll_meas_ctrl, value);
>   	rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, dpll_meas_ctrl);
>   	if (rc)
>   		return rc;
> diff --git a/drivers/dpll/zl3073x/flash.c b/drivers/dpll/zl3073x/flash.c
> index 83452a77e3e98..f85535c8ad246 100644
> --- a/drivers/dpll/zl3073x/flash.c
> +++ b/drivers/dpll/zl3073x/flash.c
> @@ -194,8 +194,7 @@ zl3073x_flash_cmd_wait(struct zl3073x_dev *zldev, u32 operation,
>   	if (rc)
>   		return rc;
>   
> -	value &= ~ZL_WRITE_FLASH_OP;
> -	value |= FIELD_PREP(ZL_WRITE_FLASH_OP, operation);
> +	FIELD_MODIFY(ZL_WRITE_FLASH_OP, &value, operation);
>   
>   	rc = zl3073x_write_u8(zldev, ZL_REG_WRITE_FLASH, value);
>   	if (rc)
LGTM.

Reviewed-by: Petr Oros <poros@redhat.com>


^ permalink raw reply

* Re: [PATCH 2/2] net: qrtr: ns: Limit the maximum lookups per socket
From: Manivannan Sadhasivam @ 2026-03-27 10:17 UTC (permalink / raw)
  To: Simon Horman
  Cc: Manivannan Sadhasivam, davem, edumazet, kuba, pabeni,
	linux-arm-msm, netdev, linux-kernel, andersson, yimingqian591,
	chris.lew, stable
In-Reply-To: <20260327100709.GD111839@horms.kernel.org>

On Fri, Mar 27, 2026 at 10:07:09AM +0000, Simon Horman wrote:
> On Wed, Mar 25, 2026 at 04:14:15PM +0530, Manivannan Sadhasivam wrote:
> > Current code does no bound checking on the number of lookups a client can
> > perform per socket. Though the code restricts the lookups to local clients,
> > there is still a possibility of a malicious local client sending a flood of
> > NEW_LOOKUP messages over the same socket.
> > 
> > Fix this issue by limiting the maximum number of lookups to 64 per socket.
> > Note that, limit of 64 is chosen based on the current platform
> > requirements. If requirement changes in the future, this limit can be
> > increased.
> > 
> > Cc: stable@vger.kernel.org
> > Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace")
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
> > ---
> >  net/qrtr/ns.c | 18 ++++++++++++++++--
> >  1 file changed, 16 insertions(+), 2 deletions(-)
> > 
> > diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
> > index fb4e8a2d370d..707fde809939 100644
> > --- a/net/qrtr/ns.c
> > +++ b/net/qrtr/ns.c
> > @@ -70,10 +70,11 @@ struct qrtr_node {
> >  	u32 server_count;
> >  };
> >  
> > -/* Max server limit is chosen based on the current platform requirements. If the
> > - * requirement changes in the future, this value can be increased.
> > +/* Max server, lookup limits are chosen based on the current platform requirements.
> > + * If the requirement changes in the future, these values can be increased.
> >   */
> >  #define QRTR_NS_MAX_SERVERS 256
> > +#define QRTR_NS_MAX_LOOKUPS 64
> >  
> >  static struct qrtr_node *node_get(unsigned int node_id)
> >  {
> > @@ -545,11 +546,24 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
> >  	struct qrtr_node *node;
> >  	unsigned long node_idx;
> >  	unsigned long srv_idx;
> > +	u8 count = 0;
> >  
> >  	/* Accept only local observers */
> >  	if (from->sq_node != qrtr_ns.local_node)
> >  		return -EINVAL;
> >  
> > +	/* Make sure the client performs only maximum allowed lookups */
> > +	list_for_each_entry(lookup, &qrtr_ns.lookups, li) {
> > +		if (lookup->sq.sq_node == from->sq_node &&
> > +		    lookup->sq.sq_port == from->sq_port)
> > +			count++;
> 
> This feels like it could get quite expensive.
> If many lookups are added, it feels like it may be O(n^2).
> 

Lookups are not something that'll happen very often. A client only registers
for the lookup once per service that it depends on. That shouldn't be too
much. And then once lookup is registered, it will be used throughout the
lifetime of the client.

So there is no overhead associated with this check.

- Mani

-- 
மணிவண்ணன் சதாசிவம்

^ permalink raw reply

* Re: [PATCH net-next 3/5] dpll: zl3073x: add ref sync and output clock type helpers
From: Petr Oros @ 2026-03-27 10:26 UTC (permalink / raw)
  To: Ivan Vecera, netdev
  Cc: Arkadiusz Kubalewski, Jiri Pirko, Michal Schmidt, Prathosh Satish,
	Simon Horman, Vadim Fedorenko, linux-kernel, Conor Dooley,
	Krzysztof Kozlowski, Rob Herring, devicetree, Pasi Vaananen
In-Reply-To: <20260319174826.7623-4-ivecera@redhat.com>

> Add ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR and ZL_REF_SYNC_CTRL_PAIR
> register definitions.
>
> Add inline helpers to get and set the sync control mode and sync pair
> fields of the reference sync control register:
>
>    zl3073x_ref_sync_mode_get/set() - ZL_REF_SYNC_CTRL_MODE field
>    zl3073x_ref_sync_pair_get/set() - ZL_REF_SYNC_CTRL_PAIR field
>
> Add inline helpers to get and set the clock type field of the output
> mode register:
>
>    zl3073x_out_clock_type_get/set() - ZL_OUTPUT_MODE_CLOCK_TYPE field
>
> Convert existing esync callbacks to use the new helpers.
>
> Signed-off-by: Ivan Vecera <ivecera@redhat.com>
> ---
>   drivers/dpll/zl3073x/dpll.c | 24 ++++++++-----------
>   drivers/dpll/zl3073x/out.h  | 22 ++++++++++++++++++
>   drivers/dpll/zl3073x/ref.h  | 46 +++++++++++++++++++++++++++++++++++++
>   drivers/dpll/zl3073x/regs.h |  2 ++
>   4 files changed, 80 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
> index 79ef62d69a32d..276f0a92db0b1 100644
> --- a/drivers/dpll/zl3073x/dpll.c
> +++ b/drivers/dpll/zl3073x/dpll.c
> @@ -137,7 +137,7 @@ zl3073x_dpll_input_pin_esync_get(const struct dpll_pin *dpll_pin,
>   	esync->range = esync_freq_ranges;
>   	esync->range_num = ARRAY_SIZE(esync_freq_ranges);
>   
> -	switch (FIELD_GET(ZL_REF_SYNC_CTRL_MODE, ref->sync_ctrl)) {
> +	switch (zl3073x_ref_sync_mode_get(ref)) {
>   	case ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75:
>   		esync->freq = ref->esync_n_div == ZL_REF_ESYNC_DIV_1HZ ? 1 : 0;
>   		esync->pulse = 25;
> @@ -173,8 +173,7 @@ zl3073x_dpll_input_pin_esync_set(const struct dpll_pin *dpll_pin,
>   	else
>   		sync_mode = ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75;
>   
> -	ref.sync_ctrl &= ~ZL_REF_SYNC_CTRL_MODE;
> -	ref.sync_ctrl |= FIELD_PREP(ZL_REF_SYNC_CTRL_MODE, sync_mode);
> +	zl3073x_ref_sync_mode_set(&ref, sync_mode);
>   
>   	if (freq) {
>   		/* 1 Hz is only supported frequency now */
> @@ -578,7 +577,7 @@ zl3073x_dpll_output_pin_esync_get(const struct dpll_pin *dpll_pin,
>   	const struct zl3073x_synth *synth;
>   	const struct zl3073x_out *out;
>   	u32 synth_freq, out_freq;
> -	u8 clock_type, out_id;
> +	u8 out_id;
>   
>   	out_id = zl3073x_output_pin_out_get(pin->id);
>   	out = zl3073x_out_state_get(zldev, out_id);
> @@ -601,8 +600,7 @@ zl3073x_dpll_output_pin_esync_get(const struct dpll_pin *dpll_pin,
>   	esync->range = esync_freq_ranges;
>   	esync->range_num = ARRAY_SIZE(esync_freq_ranges);
>   
> -	clock_type = FIELD_GET(ZL_OUTPUT_MODE_CLOCK_TYPE, out->mode);
> -	if (clock_type != ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC) {
> +	if (zl3073x_out_clock_type_get(out) != ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC) {
>   		/* No need to read esync data if it is not enabled */
>   		esync->freq = 0;
>   		esync->pulse = 0;
> @@ -635,8 +633,8 @@ zl3073x_dpll_output_pin_esync_set(const struct dpll_pin *dpll_pin,
>   	struct zl3073x_dpll_pin *pin = pin_priv;
>   	const struct zl3073x_synth *synth;
>   	struct zl3073x_out out;
> -	u8 clock_type, out_id;
>   	u32 synth_freq;
> +	u8 out_id;
>   
>   	out_id = zl3073x_output_pin_out_get(pin->id);
>   	out = *zl3073x_out_state_get(zldev, out_id);
> @@ -648,15 +646,13 @@ zl3073x_dpll_output_pin_esync_set(const struct dpll_pin *dpll_pin,
>   	if (zl3073x_out_is_ndiv(&out))
>   		return -EOPNOTSUPP;
>   
> -	/* Select clock type */
> +	/* Update clock type in output mode */
>   	if (freq)
> -		clock_type = ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC;
> +		zl3073x_out_clock_type_set(&out,
> +					   ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC);
>   	else
> -		clock_type = ZL_OUTPUT_MODE_CLOCK_TYPE_NORMAL;
> -
> -	/* Update clock type in output mode */
> -	out.mode &= ~ZL_OUTPUT_MODE_CLOCK_TYPE;
> -	out.mode |= FIELD_PREP(ZL_OUTPUT_MODE_CLOCK_TYPE, clock_type);
> +		zl3073x_out_clock_type_set(&out,
> +					   ZL_OUTPUT_MODE_CLOCK_TYPE_NORMAL);
>   
>   	/* If esync is being disabled just write mailbox and finish */
>   	if (!freq)
> diff --git a/drivers/dpll/zl3073x/out.h b/drivers/dpll/zl3073x/out.h
> index edf40432bba5f..660889c57bffa 100644
> --- a/drivers/dpll/zl3073x/out.h
> +++ b/drivers/dpll/zl3073x/out.h
> @@ -42,6 +42,28 @@ const struct zl3073x_out *zl3073x_out_state_get(struct zl3073x_dev *zldev,
>   int zl3073x_out_state_set(struct zl3073x_dev *zldev, u8 index,
>   			  const struct zl3073x_out *out);
>   
> +/**
> + * zl3073x_out_clock_type_get - get output clock type
> + * @out: pointer to out state
> + *
> + * Return: clock type of given output (ZL_OUTPUT_MODE_CLOCK_TYPE_*)
> + */
> +static inline u8 zl3073x_out_clock_type_get(const struct zl3073x_out *out)
> +{
> +	return FIELD_GET(ZL_OUTPUT_MODE_CLOCK_TYPE, out->mode);
> +}
> +
> +/**
> + * zl3073x_out_clock_type_set - set output clock type
> + * @out: pointer to out state
> + * @type: clock type (ZL_OUTPUT_MODE_CLOCK_TYPE_*)
> + */
> +static inline void
> +zl3073x_out_clock_type_set(struct zl3073x_out *out, u8 type)
> +{
> +	FIELD_MODIFY(ZL_OUTPUT_MODE_CLOCK_TYPE, &out->mode, type);
> +}
> +
>   /**
>    * zl3073x_out_signal_format_get - get output signal format
>    * @out: pointer to out state
> diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h
> index 06d8d4d97ea26..09fab97a71d7e 100644
> --- a/drivers/dpll/zl3073x/ref.h
> +++ b/drivers/dpll/zl3073x/ref.h
> @@ -106,6 +106,52 @@ zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq)
>   	return 0;
>   }
>   
> +/**
> + * zl3073x_ref_sync_mode_get - get sync control mode
> + * @ref: pointer to ref state
> + *
> + * Return: sync control mode (ZL_REF_SYNC_CTRL_MODE_*)
> + */
> +static inline u8
> +zl3073x_ref_sync_mode_get(const struct zl3073x_ref *ref)
> +{
> +	return FIELD_GET(ZL_REF_SYNC_CTRL_MODE, ref->sync_ctrl);
> +}
> +
> +/**
> + * zl3073x_ref_sync_mode_set - set sync control mode
> + * @ref: pointer to ref state
> + * @mode: sync control mode (ZL_REF_SYNC_CTRL_MODE_*)
> + */
> +static inline void
> +zl3073x_ref_sync_mode_set(struct zl3073x_ref *ref, u8 mode)
> +{
> +	FIELD_MODIFY(ZL_REF_SYNC_CTRL_MODE, &ref->sync_ctrl, mode);
> +}
> +
> +/**
> + * zl3073x_ref_sync_pair_get - get sync pair reference index
> + * @ref: pointer to ref state
> + *
> + * Return: paired reference index
> + */
> +static inline u8
> +zl3073x_ref_sync_pair_get(const struct zl3073x_ref *ref)
> +{
> +	return FIELD_GET(ZL_REF_SYNC_CTRL_PAIR, ref->sync_ctrl);
> +}
> +
> +/**
> + * zl3073x_ref_sync_pair_set - set sync pair reference index
> + * @ref: pointer to ref state
> + * @pair: paired reference index
> + */
> +static inline void
> +zl3073x_ref_sync_pair_set(struct zl3073x_ref *ref, u8 pair)
> +{
> +	FIELD_MODIFY(ZL_REF_SYNC_CTRL_PAIR, &ref->sync_ctrl, pair);
> +}
> +
>   /**
>    * zl3073x_ref_is_diff - check if the given input reference is differential
>    * @ref: pointer to ref state
> diff --git a/drivers/dpll/zl3073x/regs.h b/drivers/dpll/zl3073x/regs.h
> index 5ae50cb761a97..d425dc67250fe 100644
> --- a/drivers/dpll/zl3073x/regs.h
> +++ b/drivers/dpll/zl3073x/regs.h
> @@ -213,7 +213,9 @@
>   #define ZL_REG_REF_SYNC_CTRL			ZL_REG(10, 0x2e, 1)
>   #define ZL_REF_SYNC_CTRL_MODE			GENMASK(2, 0)
>   #define ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR_OFF	0
> +#define ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR	1
>   #define ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75	2
> +#define ZL_REF_SYNC_CTRL_PAIR			GENMASK(7, 4)
>   
>   #define ZL_REG_REF_ESYNC_DIV			ZL_REG(10, 0x30, 4)
>   #define ZL_REF_ESYNC_DIV_1HZ			0

LGTM.

Reviewed-by: Petr Oros <poros@redhat.com>



^ permalink raw reply

* Re: [PATCH net-next 4/5] dt-bindings: dpll: add ref-sync-sources property
From: Petr Oros @ 2026-03-27 10:27 UTC (permalink / raw)
  To: Ivan Vecera, netdev
  Cc: Arkadiusz Kubalewski, Jiri Pirko, Michal Schmidt, Prathosh Satish,
	Simon Horman, Vadim Fedorenko, linux-kernel, Conor Dooley,
	Krzysztof Kozlowski, Rob Herring, devicetree, Pasi Vaananen
In-Reply-To: <20260319174826.7623-5-ivecera@redhat.com>

> Add ref-sync-sources phandle-array property to the dpll-pin schema
> allowing board designers to declare which input pins can serve as
> sync sources in a Reference-Sync pair.  A Ref-Sync pair consists of
> a clock reference and a low-frequency sync signal where the DPLL locks
> to the clock but phase-aligns to the sync reference.
>
> Update both examples in the Microchip ZL3073x binding to demonstrate
> the new property with a 1 PPS sync source paired to a clock source.
>
> Signed-off-by: Ivan Vecera <ivecera@redhat.com>
> ---
>   .../devicetree/bindings/dpll/dpll-pin.yaml    | 11 +++++++
>   .../bindings/dpll/microchip,zl30731.yaml      | 30 ++++++++++++++-----
>   2 files changed, 34 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/dpll/dpll-pin.yaml b/Documentation/devicetree/bindings/dpll/dpll-pin.yaml
> index 51db93b77306f..7084f102e274c 100644
> --- a/Documentation/devicetree/bindings/dpll/dpll-pin.yaml
> +++ b/Documentation/devicetree/bindings/dpll/dpll-pin.yaml
> @@ -36,6 +36,17 @@ properties:
>       description: String exposed as the pin board label
>       $ref: /schemas/types.yaml#/definitions/string
>   
> +  ref-sync-sources:
> +    description: |
> +      List of phandles to input pins that can serve as the sync source
> +      in a Reference-Sync pair with this pin acting as the clock source.
> +      A Ref-Sync pair consists of a clock reference and a low-frequency
> +      sync signal.  The DPLL locks to the clock reference but
> +      phase-aligns to the sync reference.
> +      Only valid for input pins.  Each referenced pin must be a
> +      different input pin on the same device.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +
>     supported-frequencies-hz:
>       description: List of supported frequencies for this pin, expressed in Hz.
>   
> diff --git a/Documentation/devicetree/bindings/dpll/microchip,zl30731.yaml b/Documentation/devicetree/bindings/dpll/microchip,zl30731.yaml
> index 17747f754b845..fa5a8f8e390cd 100644
> --- a/Documentation/devicetree/bindings/dpll/microchip,zl30731.yaml
> +++ b/Documentation/devicetree/bindings/dpll/microchip,zl30731.yaml
> @@ -52,11 +52,19 @@ examples:
>             #address-cells = <1>;
>             #size-cells = <0>;
>   
> -          pin@0 { /* REF0P */
> +          sync0: pin@0 { /* REF0P - 1 PPS sync source */
>               reg = <0>;
>               connection-type = "ext";
> -            label = "Input 0";
> -            supported-frequencies-hz = /bits/ 64 <1 1000>;
> +            label = "SMA1";
> +            supported-frequencies-hz = /bits/ 64 <1>;
> +          };
> +
> +          pin@1 { /* REF0N - clock source, can pair with sync0 */
> +            reg = <1>;
> +            connection-type = "ext";
> +            label = "SMA2";
> +            supported-frequencies-hz = /bits/ 64 <10000 10000000>;
> +            ref-sync-sources = <&sync0>;
>             };
>           };
>   
> @@ -90,11 +98,19 @@ examples:
>             #address-cells = <1>;
>             #size-cells = <0>;
>   
> -          pin@0 { /* REF0P */
> +          sync1: pin@0 { /* REF0P - 1 PPS sync source */
>               reg = <0>;
> -            connection-type = "ext";
> -            label = "Input 0";
> -            supported-frequencies-hz = /bits/ 64 <1 1000>;
> +            connection-type = "gnss";
> +            label = "GNSS_1PPS_IN";
> +            supported-frequencies-hz = /bits/ 64 <1>;
> +          };
> +
> +          pin@1 { /* REF0N - clock source */
> +            reg = <1>;
> +            connection-type = "gnss";
> +            label = "GNSS_10M_IN";
> +            supported-frequencies-hz = /bits/ 64 <10000000>;
> +            ref-sync-sources = <&sync1>;
>             };
>           };
>   
LGTM.

Reviewed-by: Petr Oros <poros@redhat.com>


^ permalink raw reply

* Re: [PATCH net-next] sfc: add transmit timestamping support
From: Breno Leitao @ 2026-03-27 10:29 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Izabela Bakollari, Edward Cree, Andrew Lunn, David S. Miller,
	Eric Dumazet, Paolo Abeni, netdev, linux-net-drivers,
	linux-kernel
In-Reply-To: <20260326183951.686a522f@kernel.org>

On Thu, Mar 26, 2026 at 06:39:51PM -0700, Jakub Kicinski wrote:
> On Wed, 25 Mar 2026 02:35:12 -0700 Breno Leitao wrote:
> > On Tue, Mar 24, 2026 at 05:08:21PM +0100, Izabela Bakollari wrote:
> > > Enable software TX Timestamping. The out of tree driver 
> > > also implements this.  
> > 
> > "The out of tree driver also implements this" is not the most technical
> > justification.
> 
> +1 it's an odd thing to put in the commit msg.
> Please fix and repost (keep Ed's tag)
> 
> > > diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c
> > > index 362388754a29..c0038b942913 100644
> > > --- a/drivers/net/ethernet/sfc/ethtool.c
> > > +++ b/drivers/net/ethernet/sfc/ethtool.c
> > > @@ -231,6 +231,8 @@ static int efx_ethtool_get_ts_info(struct net_device *net_dev,
> > >  {
> > >  	struct efx_nic *efx = efx_netdev_priv(net_dev);
> > >  
> > > +	ts_info->so_timestamping = SOF_TIMESTAMPING_TX_SOFTWARE;  
> > 
> > Don't you need to append SOF_TIMESTAMPING_TX_SOFTWARE instead of
> > assinging it?
> > 
> > 	ts_info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE;
> 
> Either way is fine IMHO unless you see a specific reason Breno?

No specific reason, it is more a nit.

so_timestamping is always zero-initialized before the callback is called,
meaning = and |= are functionally equivalent today.

That said, I see these callbacks setting fields in so_timestamping, and not
overwriting it, given it does it later with it.

  ts_info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE |
                               SOF_TIMESTAMPING_RX_HARDWARE |
                               SOF_TIMESTAMPING_RAW_HARDWARE);

But again, it makes no difference in here, given the value is already zero.

^ permalink raw reply

* Re: [PATCH] net: ti: icssg-prueth: fix missing data copy and wrong recycle in ZC RX dispatch
From: Simon Horman @ 2026-03-27 10:29 UTC (permalink / raw)
  To: David Carlier
  Cc: danishanwar, rogerq, andrew+netdev, davem, edumazet, kuba, pabeni,
	m-malladi, jacob.e.keller, linux-arm-kernel, netdev, linux-kernel
In-Reply-To: <20260325125131.53399-1-devnexen@gmail.com>

+ Meghana Malladi

On Wed, Mar 25, 2026 at 12:51:30PM +0000, David Carlier wrote:
> emac_dispatch_skb_zc() allocates a new skb via napi_alloc_skb() but
> never copies the packet data from the XDP buffer into it. The skb is
> passed up the stack containing uninitialized heap memory instead of
> the actual received packet, leaking kernel heap contents to userspace.
> 
> Copy the received packet data from the XDP buffer into the skb using
> skb_copy_to_linear_data().
> 
> Additionally, remove the skb_mark_for_recycle() call since the skb is
> backed by the NAPI page frag allocator, not page_pool. Marking a
> non-page_pool skb for recycle causes the free path to return pages to
> a page_pool that does not own them, corrupting page_pool state.
> 
> The non-ZC path (emac_rx_packet) does not have these issues because it
> uses napi_build_skb() to wrap the existing page_pool page directly,
> requiring no copy, and correctly marks for recycle since the page comes
> from page_pool_dev_alloc_pages().
> 
> Fixes: 7a64bb388df3 ("net: ti: icssg-prueth: Add AF_XDP zero copy for RX")
> Signed-off-by: David Carlier <devnexen@gmail.com>
> ---
>  drivers/net/ethernet/ti/icssg/icssg_common.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Hi David,

Thanks for the update.
My understanding is that this addresses the review of v1.

Reviewed-by: Simon Horman <horms@kernel.org>

v1: https://lore.kernel.org/all/20260324211402.342474-1-devnexen@gmail.com/

Some points to keep in mind for the future:

* Please include a version number in the subject when posting versions >
  This helps a lot in tracking things.

  Subject: [PATCH v2] ...

* Please include the target tree. As a fix for code, which I asusme
  is present in net, in this case that would be the net tree.

  Subject: [PATCH net v2] ...

  Otherwise it would probably be the net-next tree.

* Please CC all relevant parties. In this case that would
  include Meghana as he provided review of v1.

* Please consider including a changelog, along with links to earlier
  versions below the scissors ("---")

* b4 can help with most of these things

* More information on the Netdev development process can be found at
  https://docs.kernel.org/process/maintainer-netdev.html

...

^ permalink raw reply

* Re: [PATCH net-next 00/10] net: lan966x: add support for PCIe FDMA
From: Herve Codina @ 2026-03-27 10:33 UTC (permalink / raw)
  To: Daniel Machon
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Horatiu Vultur, Steen Hegelund, UNGLinuxDriver,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Arnd Bergmann,
	Greg Kroah-Hartman, netdev, linux-kernel, bpf
In-Reply-To: <20260326154833.jp6rx5x2rlpmwrg3@DEN-DL-M70577>

Hi Daniel,

On Thu, 26 Mar 2026 16:48:33 +0100
Daniel Machon <daniel.machon@microchip.com> wrote:

...

> 
> As I remembered, doing rmmod on the lan966x_switch followed by modprobe
> lan966x_switch works fine. This is because neither the switch core, nor the FDMA
> engine is reset, so they remain in sync.
> 
> When the lan966x_pci module is removed and reloaded (what you did), the DT
> overlay is re-applied, which causes the reset controller
> (reset-microchip-sparx5) to re-probe. During probe, it performs a GCB soft reset
> that resets the switch core, but protects the CPU domain from the reset. The
> FDMA engine is part of the CPU domain, so it is not reset.
> 
> This leaves the switch core in a reset state while the FDMA
> retains state from the previous driver instance. When the switch driver
> subsequently probes and activates the FDMA channels, the two are out of
> sync, and the FDMA immediately reports extraction errors.
> 
> Theres actually an FDMA register called NRESET that resets the FDMA controller
> state. Calling this in the FDMA init path causes traffic to work correctly on
> lan966x_pci reload, but it does not get rid of the FDMA splats you posted above.
> They get queued up between the switch core reset, in the reset controller, and
> the FDMA enabling. I tried different approaches to drain or flush queues, but
> they wont go away entirely.
> 
> The only thing that seems to work consistently is to *not* do the soft reset in
> the reset controller for the PCI path. The soft reset is actually the problem:
> it only resets the switch core while protecting the CPU domain (including FDMA),
> causing a desync.
> 
> A simple fix could be (in reset-microchip-sparx5.c):
> 
> +static bool mchp_reset_is_pci(struct device *dev)
> +{
> +	for (dev = dev->parent; dev; dev = dev->parent) {
> +		if (dev_is_pci(dev))
> +			return true;
> +	}
> +	return false;
> +}
> 
> -	/* Issue the reset very early, our actual reset callback is a noop. */
> -	err = sparx5_switch_reset(ctx);
> -	if (err)
> -		return err;
> +	/* Issue the reset very early, our actual reset callback is a noop.
> +	 *
> +	 * On the PCI path, skip the reset. The endpoint is already in
> +	 * power-on reset state on the first probe. On subsequent probes
> +	 * (after driver reload), resetting the switch core while the FDMA
> +	 * retains state (CPU domain is protected from the soft reset)
> +	 * causes the two to go out of sync, leading to FDMA extraction
> +	 * errors.
> +	 */
> +	if (!mchp_reset_is_pci(&pdev->dev)) {
> +		err = sparx5_switch_reset(ctx);
> +		if (err)
> +			return err;
> +	}
> 
> Could you test it and see if it helps the problem on your side.
> 

I have tested it on my ARM and x86 system. It fixes the lan966x_pci module
unloading / reloading issue.

However an other regression is present. After a reboot, without power
off/on, the board is not working (tested on both my ARM and x86 systems).

According to your explanation, this makes sense.

IMHO, the problem is that we cannot make the assumption that "The endpoint
is already in power-on reset state on the first probe". That's not true
when you just call the reboot command.

Best regards,
Hervé

^ permalink raw reply

* Re: [PATCH net-next 5/5] dpll: zl3073x: add ref-sync pair support
From: Petr Oros @ 2026-03-27 10:34 UTC (permalink / raw)
  To: Ivan Vecera, netdev
  Cc: Arkadiusz Kubalewski, Jiri Pirko, Michal Schmidt, Prathosh Satish,
	Simon Horman, Vadim Fedorenko, linux-kernel, Conor Dooley,
	Krzysztof Kozlowski, Rob Herring, devicetree, Pasi Vaananen
In-Reply-To: <20260319174826.7623-6-ivecera@redhat.com>

> Add support for ref-sync pair registration using the 'ref-sync-sources'
> phandle property from device tree. A ref-sync pair consists of a clock
> reference and a low-frequency sync signal where the DPLL locks to the
> clock reference but phase-aligns to the sync reference.
>
> The implementation:
> - Stores fwnode handle in zl3073x_dpll_pin during pin registration
> - Adds ref_sync_get/set callbacks to read and write the sync control
>    mode and pair registers
> - Validates ref-sync frequency constraints: sync signal must be 8 kHz
>    or less, clock reference must be 1 kHz or more and higher than sync
> - Excludes sync source from automatic reference selection by setting
>    its priority to NONE on connect; on disconnect the priority is left
>    as NONE and the user must explicitly make the pin selectable again
> - Iterates ref-sync-sources phandles to register declared pairings
>    via dpll_pin_ref_sync_pair_add()
>
> Signed-off-by: Ivan Vecera <ivecera@redhat.com>
> ---
>   drivers/dpll/zl3073x/dpll.c | 207 +++++++++++++++++++++++++++++++++++-
>   1 file changed, 206 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
> index 276f0a92db0b1..8010e2635f641 100644
> --- a/drivers/dpll/zl3073x/dpll.c
> +++ b/drivers/dpll/zl3073x/dpll.c
> @@ -13,6 +13,7 @@
>   #include <linux/module.h>
>   #include <linux/netlink.h>
>   #include <linux/platform_device.h>
> +#include <linux/property.h>
>   #include <linux/slab.h>
>   #include <linux/sprintf.h>
>   
> @@ -30,6 +31,7 @@
>    * @dpll: DPLL the pin is registered to
>    * @dpll_pin: pointer to registered dpll_pin
>    * @tracker: tracking object for the acquired reference
> + * @fwnode: firmware node handle
>    * @label: package label
>    * @dir: pin direction
>    * @id: pin id
> @@ -45,6 +47,7 @@ struct zl3073x_dpll_pin {
>   	struct zl3073x_dpll	*dpll;
>   	struct dpll_pin		*dpll_pin;
>   	dpll_tracker		tracker;
> +	struct fwnode_handle	*fwnode;
>   	char			label[8];
>   	enum dpll_pin_direction	dir;
>   	u8			id;
> @@ -184,6 +187,109 @@ zl3073x_dpll_input_pin_esync_set(const struct dpll_pin *dpll_pin,
>   	return zl3073x_ref_state_set(zldev, ref_id, &ref);
>   }
>   
> +static int
> +zl3073x_dpll_input_pin_ref_sync_get(const struct dpll_pin *dpll_pin,
> +				    void *pin_priv,
> +				    const struct dpll_pin *ref_sync_pin,
> +				    void *ref_sync_pin_priv,
> +				    enum dpll_pin_state *state,
> +				    struct netlink_ext_ack *extack)
> +{
> +	struct zl3073x_dpll_pin *sync_pin = ref_sync_pin_priv;
> +	struct zl3073x_dpll_pin *pin = pin_priv;
> +	struct zl3073x_dpll *zldpll = pin->dpll;
> +	struct zl3073x_dev *zldev = zldpll->dev;
> +	const struct zl3073x_ref *ref;
> +	u8 ref_id, mode, pair;
> +
> +	ref_id = zl3073x_input_pin_ref_get(pin->id);
> +	ref = zl3073x_ref_state_get(zldev, ref_id);
> +	mode = zl3073x_ref_sync_mode_get(ref);
> +	pair = zl3073x_ref_sync_pair_get(ref);
> +
> +	if (mode == ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR &&
> +	    pair == zl3073x_input_pin_ref_get(sync_pin->id))
> +		*state = DPLL_PIN_STATE_CONNECTED;
> +	else
> +		*state = DPLL_PIN_STATE_DISCONNECTED;
> +
> +	return 0;
> +}
> +
> +static int
> +zl3073x_dpll_input_pin_ref_sync_set(const struct dpll_pin *dpll_pin,
> +				    void *pin_priv,
> +				    const struct dpll_pin *ref_sync_pin,
> +				    void *ref_sync_pin_priv,
> +				    const enum dpll_pin_state state,
> +				    struct netlink_ext_ack *extack)
> +{
> +	struct zl3073x_dpll_pin *sync_pin = ref_sync_pin_priv;
> +	struct zl3073x_dpll_pin *pin = pin_priv;
> +	struct zl3073x_dpll *zldpll = pin->dpll;
> +	struct zl3073x_dev *zldev = zldpll->dev;
> +	u8 mode, ref_id, sync_ref_id;
> +	struct zl3073x_chan chan;
> +	struct zl3073x_ref ref;
> +	int rc;
> +
> +	ref_id = zl3073x_input_pin_ref_get(pin->id);
> +	sync_ref_id = zl3073x_input_pin_ref_get(sync_pin->id);
> +	ref = *zl3073x_ref_state_get(zldev, ref_id);
> +
> +	if (state == DPLL_PIN_STATE_CONNECTED) {
> +		const struct zl3073x_ref *sync_ref;
> +		u32 ref_freq, sync_freq;
> +
> +		sync_ref = zl3073x_ref_state_get(zldev, sync_ref_id);
> +		ref_freq = zl3073x_ref_freq_get(&ref);
> +		sync_freq = zl3073x_ref_freq_get(sync_ref);
> +
> +		/* Sync signal must be 8 kHz or less and clock reference
> +		 * must be 1 kHz or more and higher than the sync signal.
> +		 */
> +		if (sync_freq > 8000) {
> +			NL_SET_ERR_MSG(extack,
> +				       "sync frequency must be 8 kHz or less");
> +			return -EINVAL;
> +		}
> +		if (ref_freq < 1000) {
> +			NL_SET_ERR_MSG(extack,
> +				       "clock frequency must be 1 kHz or more");
> +			return -EINVAL;
> +		}
> +		if (ref_freq <= sync_freq) {
> +			NL_SET_ERR_MSG(extack,
> +				       "clock frequency must be higher than sync frequency");
> +			return -EINVAL;
> +		}
> +
> +		zl3073x_ref_sync_pair_set(&ref, sync_ref_id);
> +		mode = ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR;
> +	} else {
> +		mode = ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR_OFF;
> +	}
> +
> +	zl3073x_ref_sync_mode_set(&ref, mode);
> +
> +	rc = zl3073x_ref_state_set(zldev, ref_id, &ref);
> +	if (rc)
> +		return rc;
> +
> +	/* Exclude sync source from automatic reference selection by setting
> +	 * its priority to NONE. On disconnect the priority is left as NONE
> +	 * and the user must explicitly make the pin selectable again.
> +	 */
> +	if (state == DPLL_PIN_STATE_CONNECTED) {
> +		chan = *zl3073x_chan_state_get(zldev, zldpll->id);
> +		zl3073x_chan_ref_prio_set(&chan, sync_ref_id,
> +					  ZL_DPLL_REF_PRIO_NONE);
> +		return zl3073x_chan_state_set(zldev, zldpll->id, &chan);
> +	}
> +
> +	return 0;
> +}
> +
>   static int
>   zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *dpll_pin, void *pin_priv,
>   			       const struct dpll_device *dpll, void *dpll_priv,
> @@ -1100,6 +1206,8 @@ static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops = {
>   	.phase_adjust_set = zl3073x_dpll_input_pin_phase_adjust_set,
>   	.prio_get = zl3073x_dpll_input_pin_prio_get,
>   	.prio_set = zl3073x_dpll_input_pin_prio_set,
> +	.ref_sync_get = zl3073x_dpll_input_pin_ref_sync_get,
> +	.ref_sync_set = zl3073x_dpll_input_pin_ref_sync_set,
>   	.state_on_dpll_get = zl3073x_dpll_input_pin_state_on_dpll_get,
>   	.state_on_dpll_set = zl3073x_dpll_input_pin_state_on_dpll_set,
>   };
> @@ -1190,8 +1298,11 @@ zl3073x_dpll_pin_register(struct zl3073x_dpll_pin *pin, u32 index)
>   	if (IS_ERR(props))
>   		return PTR_ERR(props);
>   
> -	/* Save package label, esync capability and phase adjust granularity */
> +	/* Save package label, fwnode, esync capability and phase adjust
> +	 * granularity.
> +	 */
>   	strscpy(pin->label, props->package_label);
> +	pin->fwnode = fwnode_handle_get(props->fwnode);
>   	pin->esync_control = props->esync_control;
>   	pin->phase_gran = props->dpll_props.phase_gran;
>   
> @@ -1236,6 +1347,8 @@ zl3073x_dpll_pin_register(struct zl3073x_dpll_pin *pin, u32 index)
>   	dpll_pin_put(pin->dpll_pin, &pin->tracker);
>   	pin->dpll_pin = NULL;
>   err_pin_get:
> +	fwnode_handle_put(pin->fwnode);
> +	pin->fwnode = NULL;
>   	zl3073x_pin_props_put(props);
>   
>   	return rc;
> @@ -1265,6 +1378,9 @@ zl3073x_dpll_pin_unregister(struct zl3073x_dpll_pin *pin)
>   
>   	dpll_pin_put(pin->dpll_pin, &pin->tracker);
>   	pin->dpll_pin = NULL;
> +
> +	fwnode_handle_put(pin->fwnode);
> +	pin->fwnode = NULL;
>   }
>   
>   /**
> @@ -1735,6 +1851,88 @@ zl3073x_dpll_free(struct zl3073x_dpll *zldpll)
>   	kfree(zldpll);
>   }
>   
> +/**
> + * zl3073x_dpll_ref_sync_pair_register - register ref_sync pairs for a pin
> + * @pin: pointer to zl3073x_dpll_pin structure
> + *
> + * Iterates 'ref-sync-sources' phandles in the pin's firmware node and
> + * registers each declared pairing.
> + *
> + * Return: 0 on success, <0 on error
> + */
> +static int
> +zl3073x_dpll_ref_sync_pair_register(struct zl3073x_dpll_pin *pin)
> +{
> +	struct zl3073x_dev *zldev = pin->dpll->dev;
> +	struct fwnode_handle *fwnode;
> +	struct dpll_pin *sync_pin;
> +	dpll_tracker tracker;
> +	int n, rc;
> +
> +	for (n = 0; ; n++) {
> +		/* Get n'th ref-sync source */
> +		fwnode = fwnode_find_reference(pin->fwnode, "ref-sync-sources",
> +					       n);
> +		if (IS_ERR(fwnode)) {
> +			rc = PTR_ERR(fwnode);
> +			break;
> +		}
> +
> +		/* Find associated dpll pin */
> +		sync_pin = fwnode_dpll_pin_find(fwnode, &tracker);
> +		fwnode_handle_put(fwnode);
> +		if (!sync_pin) {
> +			dev_warn(zldev->dev, "%s: ref-sync source %d not found",
> +				 pin->label, n);
> +			continue;
> +		}
> +
> +		/* Register new ref-sync pair */
> +		rc = dpll_pin_ref_sync_pair_add(pin->dpll_pin, sync_pin);
> +		dpll_pin_put(sync_pin, &tracker);
> +
> +		/* -EBUSY means pairing already exists from another DPLL's
> +		 * registration.
> +		 */
> +		if (rc && rc != -EBUSY) {
> +			dev_err(zldev->dev,
> +				"%s: failed to add ref-sync source %d: %pe",
> +				pin->label, n, ERR_PTR(rc));
> +			break;
> +		}
> +	}
> +
> +	return rc != -ENOENT ? rc : 0;
> +}
> +
> +/**
> + * zl3073x_dpll_ref_sync_pairs_register - register ref_sync pairs for a DPLL
> + * @zldpll: pointer to zl3073x_dpll structure
> + *
> + * Iterates all registered input pins of the given DPLL and establishes
> + * ref_sync pairings declared by 'ref-sync-sources' phandles in the
> + * device tree.
> + *
> + * Return: 0 on success, <0 on error
> + */
> +static int
> +zl3073x_dpll_ref_sync_pairs_register(struct zl3073x_dpll *zldpll)
> +{
> +	struct zl3073x_dpll_pin *pin;
> +	int rc;
> +
> +	list_for_each_entry(pin, &zldpll->pins, list) {
> +		if (!zl3073x_dpll_is_input_pin(pin) || !pin->fwnode)
> +			continue;
> +
> +		rc = zl3073x_dpll_ref_sync_pair_register(pin);
> +		if (rc)
> +			return rc;
> +	}
> +
> +	return 0;
> +}
> +
>   /**
>    * zl3073x_dpll_register - register DPLL device and all its pins
>    * @zldpll: pointer to zl3073x_dpll structure
> @@ -1758,6 +1956,13 @@ zl3073x_dpll_register(struct zl3073x_dpll *zldpll)
>   		return rc;
>   	}
>   
> +	rc = zl3073x_dpll_ref_sync_pairs_register(zldpll);
> +	if (rc) {
> +		zl3073x_dpll_pins_unregister(zldpll);
> +		zl3073x_dpll_device_unregister(zldpll);
> +		return rc;
> +	}
> +
>   	return 0;
>   }
>   

LGTM.


Reviewed-by: Petr Oros <poros@redhat.com>


^ permalink raw reply

* RE: [Intel-wired-lan] [PATCH v2 3/4] ice: use bitmap_empty() in ice_vf_has_no_qs_ena
From: Romanowski, Rafal @ 2026-03-27 10:37 UTC (permalink / raw)
  To: Loktionov, Aleksandr, Yury Norov, Nguyen, Anthony L,
	David S. Miller, Thomas Hellström, Andrew Lunn,
	Andrew Morton, David Airlie, Eric Dumazet, Jakub Kicinski,
	Brost, Matthew, Paolo Abeni, Kitszel, Przemyslaw, Vivi, Rodrigo,
	Simona Vetter, Yury Norov, Rasmus Villemoes,
	dri-devel@lists.freedesktop.org, intel-xe@lists.freedesktop.org,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	intel-wired-lan@lists.osuosl.org
  Cc: Simon Horman, David Laight
In-Reply-To: <IA3PR11MB8986F3692384856A06EACA7DE57EA@IA3PR11MB8986.namprd11.prod.outlook.com>

> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of
> Loktionov, Aleksandr
> Sent: Monday, March 2, 2026 8:14 AM
> To: Yury Norov <ynorov@nvidia.com>; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; David S. Miller <davem@davemloft.net>;
> Thomas Hellström <thomas.hellstrom@linux.intel.com>; Andrew Lunn
> <andrew+netdev@lunn.ch>; Andrew Morton <akpm@linux-foundation.org>;
> David Airlie <airlied@gmail.com>; Eric Dumazet <edumazet@google.com>; Jakub
> Kicinski <kuba@kernel.org>; Brost, Matthew <matthew.brost@intel.com>; Paolo
> Abeni <pabeni@redhat.com>; Kitszel, Przemyslaw
> <przemyslaw.kitszel@intel.com>; Vivi, Rodrigo <rodrigo.vivi@intel.com>; Simona
> Vetter <simona@ffwll.ch>; Yury Norov <yury.norov@gmail.com>; Rasmus
> Villemoes <linux@rasmusvillemoes.dk>; dri-devel@lists.freedesktop.org; intel-
> xe@lists.freedesktop.org; linux-kernel@vger.kernel.org; netdev@vger.kernel.org;
> intel-wired-lan@lists.osuosl.org
> Cc: Simon Horman <horms@kernel.org>; David Laight
> <david.laight.linux@gmail.com>
> Subject: Re: [Intel-wired-lan] [PATCH v2 3/4] ice: use bitmap_empty() in
> ice_vf_has_no_qs_ena
> 
> 
> 
> > -----Original Message-----
> > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> > Of Yury Norov via Intel-wired-lan
> > Sent: Monday, March 2, 2026 2:12 AM
> > To: Nguyen, Anthony L <anthony.l.nguyen@intel.com>; David S. Miller
> > <davem@davemloft.net>; Thomas Hellström
> > <thomas.hellstrom@linux.intel.com>; Andrew Lunn
> > <andrew+netdev@lunn.ch>; Andrew Morton <akpm@linux-foundation.org>;
> > David Airlie <airlied@gmail.com>; Eric Dumazet <edumazet@google.com>;
> > Jakub Kicinski <kuba@kernel.org>; Brost, Matthew
> > <matthew.brost@intel.com>; Paolo Abeni <pabeni@redhat.com>; Kitszel,
> > Przemyslaw <przemyslaw.kitszel@intel.com>; Vivi, Rodrigo
> > <rodrigo.vivi@intel.com>; Simona Vetter <simona@ffwll.ch>; Yury Norov
> > <yury.norov@gmail.com>; Rasmus Villemoes <linux@rasmusvillemoes.dk>;
> > dri-devel@lists.freedesktop.org; intel-xe@lists.freedesktop.org;
> > linux-kernel@vger.kernel.org; netdev@vger.kernel.org; intel-wired-
> > lan@lists.osuosl.org
> > Cc: Yury Norov <ynorov@nvidia.com>; Simon Horman <horms@kernel.org>;
> > David Laight <david.laight.linux@gmail.com>
> > Subject: [Intel-wired-lan] [PATCH v2 3/4] ice: use bitmap_empty() in
> > ice_vf_has_no_qs_ena
> >
> > bitmap_empty() is more verbose and efficient, as it stops traversing
> > {r,t}xq_ena as soon as the 1st set bit found.
> >
> > Signed-off-by: Yury Norov <ynorov@nvidia.com>
> > ---
> >  drivers/net/ethernet/intel/ice/ice_vf_lib.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> > b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> > index c8bc952f05cd..772f6b07340d 100644
> > --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> > +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
> > @@ -1210,8 +1210,8 @@ bool ice_is_vf_trusted(struct ice_vf *vf)
> >   */
> >  bool ice_vf_has_no_qs_ena(struct ice_vf *vf)  {
> > -	return (!bitmap_weight(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF) &&
> > -		!bitmap_weight(vf->txq_ena, ICE_MAX_RSS_QS_PER_VF));
> > +	return bitmap_empty(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF) &&
> > +		bitmap_empty(vf->txq_ena, ICE_MAX_RSS_QS_PER_VF);
> >  }
> >
> >  /**
> > --
> > 2.43.0
> 
> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>

Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>


^ permalink raw reply

* Re: [PATCH net-next] net: add sysctl to toggle napi_consume_skb() alien skb defer
From: Jason Xing @ 2026-03-27 10:37 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: davem, kuba, pabeni, horms, netdev
In-Reply-To: <CAL+tcoBL5+qSQhz8BO0ozOoEE0EgPpaoaPvp455e+gqrRyrEUQ@mail.gmail.com>

On Fri, Mar 27, 2026 at 12:21 AM Jason Xing <kerneljasonxing@gmail.com> wrote:
...
> > Seems a copy/paste of proc_do_static_key() ?
>
> Thanks, Eric. Much simpler right now:
> diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
> index b508618bfc12..a6a1b2c3f8e1 100644
> --- a/net/core/sysctl_net_core.c
> +++ b/net/core/sysctl_net_core.c
> @@ -676,6 +676,16 @@ static struct ctl_table net_core_table[] = {
>                 .proc_handler   = proc_do_skb_defer_max,
>                 .extra1         = SYSCTL_ZERO,
>         },
> +       {
> +               .procname       = "napi_consume_skb_defer",
> +               .data           = &napi_consume_skb_defer_key.key,
> +               .maxlen         = sizeof(napi_consume_skb_defer_key),
> +               .mode           = 0644,
> +               .proc_handler   = proc_do_static_key,
> +       },
>  };

Eric, when I'm investigating the static key feature, I wonder if we
can replace some sysctl knob that only carries either 1 or 2 with a
corresponding static key? The merits are 1) we can minimize the size
of net.core.xxx or net_hotdata which helps put the structure into one
cache line, 2) in hot paths, the static key can be more efficient.

Here is the list that I've found so far:
1. sysctl_bypass_prot_mem
2. sysctl_tstamp_allow_data
3. net_hotdata.tstamp_prequeue
4. sysctl_tcp_early_demux
5. sysctl_ip_early_demux
6. sysctl_tcp_l3mdev_accept
7. sysctl_tcp_moderate_rcvbuf
8. sysctl_tcp_nometrics_save
9. sysctl_tcp_no_ssthresh_metrics_save
10. sysctl_tcp_dsack
11. sysctl_tcp_abort_on_overflow
12. sysctl_tcp_slow_start_after_idle
13. sysctl_tcp_timestamps
...(some other tcp sysctls)...

Some of them can be accessed in multiple places, which means they can
be hot. Maybe we can try some relatively hot knobs first, like
sysctl_tcp_timestamps, sysctl_tcp_early_demux...? Do you think it's
feasible?

Thanks,
Jason

^ permalink raw reply

* Re: [PATCH] net: ti: icssg-prueth: fix missing data copy and wrong recycle in ZC RX dispatch
From: David CARLIER @ 2026-03-27 10:39 UTC (permalink / raw)
  To: Simon Horman
  Cc: danishanwar, rogerq, andrew+netdev, davem, edumazet, kuba, pabeni,
	m-malladi, jacob.e.keller, linux-arm-kernel, netdev, linux-kernel
In-Reply-To: <20260327102924.GF111839@horms.kernel.org>

Hi Simon and thanks for the feedback, will keep this in mind. Cheers !

On Fri, 27 Mar 2026 at 10:29, Simon Horman <horms@kernel.org> wrote:
>
> + Meghana Malladi
>
> On Wed, Mar 25, 2026 at 12:51:30PM +0000, David Carlier wrote:
> > emac_dispatch_skb_zc() allocates a new skb via napi_alloc_skb() but
> > never copies the packet data from the XDP buffer into it. The skb is
> > passed up the stack containing uninitialized heap memory instead of
> > the actual received packet, leaking kernel heap contents to userspace.
> >
> > Copy the received packet data from the XDP buffer into the skb using
> > skb_copy_to_linear_data().
> >
> > Additionally, remove the skb_mark_for_recycle() call since the skb is
> > backed by the NAPI page frag allocator, not page_pool. Marking a
> > non-page_pool skb for recycle causes the free path to return pages to
> > a page_pool that does not own them, corrupting page_pool state.
> >
> > The non-ZC path (emac_rx_packet) does not have these issues because it
> > uses napi_build_skb() to wrap the existing page_pool page directly,
> > requiring no copy, and correctly marks for recycle since the page comes
> > from page_pool_dev_alloc_pages().
> >
> > Fixes: 7a64bb388df3 ("net: ti: icssg-prueth: Add AF_XDP zero copy for RX")
> > Signed-off-by: David Carlier <devnexen@gmail.com>
> > ---
> >  drivers/net/ethernet/ti/icssg/icssg_common.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
>
> Hi David,
>
> Thanks for the update.
> My understanding is that this addresses the review of v1.
>
> Reviewed-by: Simon Horman <horms@kernel.org>
>
> v1: https://lore.kernel.org/all/20260324211402.342474-1-devnexen@gmail.com/
>
> Some points to keep in mind for the future:
>
> * Please include a version number in the subject when posting versions >
>   This helps a lot in tracking things.
>
>   Subject: [PATCH v2] ...
>
> * Please include the target tree. As a fix for code, which I asusme
>   is present in net, in this case that would be the net tree.
>
>   Subject: [PATCH net v2] ...
>
>   Otherwise it would probably be the net-next tree.
>
> * Please CC all relevant parties. In this case that would
>   include Meghana as he provided review of v1.
>
> * Please consider including a changelog, along with links to earlier
>   versions below the scissors ("---")
>
> * b4 can help with most of these things
>
> * More information on the Netdev development process can be found at
>   https://docs.kernel.org/process/maintainer-netdev.html
>
> ...

^ permalink raw reply

* Re: [PATCH 5/5] nbd: Use lock_sock_try() for TCP sendmsg() and shutdown().
From: kernel test robot @ 2026-03-27 10:40 UTC (permalink / raw)
  To: Kuniyuki Iwashima, Josef Bacik, Jens Axboe, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: oe-kbuild-all, Simon Horman, Kuniyuki Iwashima, linux-block, nbd,
	netdev, syzbot+7b4f368d3955d2c9950e
In-Reply-To: <20260325063843.1790782-6-kuniyu@google.com>

Hi Kuniyuki,

kernel test robot noticed the following build errors:

[auto build test ERROR on axboe/for-next]
[also build test ERROR on linus/master v7.0-rc5]
[cannot apply to next-20260326]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Kuniyuki-Iwashima/nbd-Remove-redundant-sock-ops-shutdown-check-in-nbd_get_socket/20260325-175457
base:   https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux.git for-next
patch link:    https://lore.kernel.org/r/20260325063843.1790782-6-kuniyu%40google.com
patch subject: [PATCH 5/5] nbd: Use lock_sock_try() for TCP sendmsg() and shutdown().
config: arm64-randconfig-003-20260326 (https://download.01.org/0day-ci/archive/20260327/202603271810.hoQGfrEp-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.4.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260327/202603271810.hoQGfrEp-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603271810.hoQGfrEp-lkp@intel.com/

All errors (new ones prefixed by >>):

   aarch64-linux-ld: Unexpected GOT/PLT entries detected!
   aarch64-linux-ld: Unexpected run-time procedure linkages detected!
   aarch64-linux-ld: drivers/block/nbd.o: in function `nbd_mark_nsock_dead':
>> nbd.c:(.text+0x1238): undefined reference to `inet_shutdown_locked'
   aarch64-linux-ld: drivers/block/nbd.o: in function `__sock_xmit':
>> nbd.c:(.text+0x4fbc): undefined reference to `tcp_sendmsg_locked'

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH net-next] mlx5: shd: Gracefully avoid shared devlink creation when no usable SN is found
From: Simon Horman @ 2026-03-27 10:42 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, edumazet, kuba, pabeni, andrew+netdev, saeedm,
	leon, tariqt, mbloch, admiyo, ben.copeland
In-Reply-To: <20260325152801.236343-1-jiri@resnulli.us>

On Wed, Mar 25, 2026 at 04:28:01PM +0100, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@nvidia.com>
> 
> On some HW, not even fall-back "SERIALNO" is found in VPD data. Unify
> the behavior with the case there are no VPD data at all and avoid
> creation of shared devlink instance.
> 
> Fixes: 2a8c8a03f306 ("net/mlx5: Add a shared devlink instance for PFs on same chip")
> Reported-by: Adam Young <admiyo@amperemail.onmicrosoft.com>
> Closes: https://lore.kernel.org/all/bab5b6bc-aa42-4af1-80d1-e56bcef06bc2@amperemail.onmicrosoft.com/
> Reported-by: Ben Copeland <ben.copeland@linaro.org>
> Closes: https://lore.kernel.org/all/20260324151014.860376-1-ben.copeland@linaro.org/
> Signed-off-by: Jiri Pirko <jiri@nvidia.com>

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply

* Re: [PATCH iwl-next v3] ice: add 200G_AUI8 PHY type definitions and wire them up
From: Simon Horman @ 2026-03-27 10:47 UTC (permalink / raw)
  To: Aleksandr Loktionov
  Cc: intel-wired-lan, anthony.l.nguyen, netdev, Paul Greenwalt,
	Paul Menzel
In-Reply-To: <20260324153542.674859-1-aleksandr.loktionov@intel.com>

On Tue, Mar 24, 2026 at 04:35:42PM +0100, Aleksandr Loktionov wrote:
> ice_link_mode_str_high[] lacks entries for phy_type_high bits 5-14
> (all 200G PHY types on E825C); ice_dump_phy_type() prints nothing for
> them when ICE_DBG_LINK is set (e.g. 'ethtool -s ethX msglvl 0x10').
> The loop also iterates all 64 bits against a 5-entry array - undefined
> behaviour for any matched bit beyond the end.  Add strings for bits
> 5-14 and guard the loop with ARRAY_SIZE(), falling back to "unknown"
> for unrecognised bits.
> 
> ICE_PHY_TYPE_HIGH_200G_AUI8_AOC_ACC (bit 13) and 200G_AUI8 (bit 14)
> were absent from ice_adminq_cmd.h; ICE_PHY_TYPE_HIGH_MAX_INDEX capped
> at 12 caused ice_update_phy_type() to skip them entirely, leaving both
> invisible to 200G speed requests.  Add the definitions and bump
> MAX_INDEX to 14.
> 
> Wire the two new types throughout the driver:
> - ice_get_media_type(): handle all ten 200G phy_type_high values so
>   E825C ports no longer return ICE_MEDIA_UNKNOWN.  AOC_ACC interfaces
>   map to FIBER; bare AUI4/AUI8 to DA with cage, else BACKPLANE
>   (matching existing AUI2/CAUI2 logic); CR4_PAM4 to DA; SR4/FR4/LR4/
>   DR4 to FIBER; KR4_PAM4 to BACKPLANE.
> - ice_get_link_speed_based_on_phy_type(): return ICE_AQ_LINK_SPEED_200GB
>   for both new types so ice_update_phy_type() enables them correctly.
> - phy_type_high_lkup[13,14]: AUI8 is 8-lane 25G-per-lane; no
>   200000baseSR8/CR8 ethtool modes exist yet, so approximate with
>   SR4_Full/CR4_Full - matching AUI4 at indices 11-12.  FIXME once
>   those link modes land upstream.
> - ICE_PHY_TYPE_HIGH_MASK_200G: add bits 13-14 for the minimum-speed
>   floor in ice_mask_min_supported_speeds().
> 
> Suggested-by: Paul Greenwalt <paul.greenwalt@intel.com>
> Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> Cc: Simon Horman <horms@kernel.org>
> Cc: Paul Menzel <pmenzel@molgen.mpg.de>
> ---
> v3 -> v4: add ARRAY_SIZE() OOB guard in ice_dump_phy_type(); cover all
>           ten 200G phy_type_high values in ice_get_media_type(); add FIXME
>           to lkup[13..14] for missing SR8/CR8 modes; rename subject
>           fix subject; fix debug enable example (ethtool, not modprobe);
>           add AUI8 speed mapping, lkup[13-14], MASK_200G bits 13-14,
>           and AUI8->SR4/CR4 approximation comment
> v1 -> v2: add ICE_PHY_TYPE_HIGH_MAX_INDEX update

Thanks for the updates.

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply

* Re: [PATCH v2 3/5] bpf: add helper masks for ADJ_ROOM flags and encap validation
From: Hudson, Nick @ 2026-03-27 10:55 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: Willem de Bruijn, Tottenham, Max, Glasgall, Anna,
	Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	bpf@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <c0c453f9-28aa-462f-884d-0e9beb2fdf0a@linux.dev>

[-- Attachment #1: Type: text/plain, Size: 1272 bytes --]



> On Mar 26, 2026, at 5:49 PM, Martin KaFai Lau <martin.lau@linux.dev> wrote:
> 
> !-------------------------------------------------------------------|
> This Message Is From an External Sender
> This message came from outside your organization.
> |-------------------------------------------------------------------!
> 
> 
> 
> On 3/26/26 10:02 AM, Hudson, Nick wrote:
>>>>    static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
>>>>       u64 flags)
>>>> @@ -3502,6 +3513,11 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 off, u32 len_diff,
>>>>   unsigned int gso_type = SKB_GSO_DODGY;
>>>>   int ret;
>>>>  + if (unlikely(flags & ~(BPF_F_ADJ_ROOM_ENCAP_MASK |
>>>> +        BPF_F_ADJ_ROOM_NO_CSUM_RESET |
>>>> +        BPF_F_ADJ_ROOM_FIXED_GSO)))
>>> Under which case this new check will be hit?
>> If a user supplies +ve len_diff and attempts to pass a DECAP flag.
>> The commit message had
>>     Add flag validation to bpf_skb_net_grow() to reject invalid encap
>>     flags early.
> 
> There is DECAP_MASK check in bpf_skb_adjust_room() and then !shrink is rejected. What am I missing?

Duh, right.

Do you prefer the do all the flag checking in bpf_skb_adjust_room or keep the encap/decap split?


[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 3066 bytes --]

^ permalink raw reply

* Re: [PATCH net-next 00/10] net: lan966x: add support for PCIe FDMA
From: Daniel Machon @ 2026-03-27 11:07 UTC (permalink / raw)
  To: Herve Codina
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Horatiu Vultur, Steen Hegelund, UNGLinuxDriver,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Arnd Bergmann,
	Greg Kroah-Hartman, netdev, linux-kernel, bpf
In-Reply-To: <20260327113337.0368eea3@bootlin.com>

Hi Hervé,

> Hi Daniel,
> 
> On Thu, 26 Mar 2026 16:48:33 +0100
> Daniel Machon <daniel.machon@microchip.com> wrote:
> 
> ...
> 
> >
> > As I remembered, doing rmmod on the lan966x_switch followed by modprobe
> > lan966x_switch works fine. This is because neither the switch core, nor the FDMA
> > engine is reset, so they remain in sync.
> >
> > When the lan966x_pci module is removed and reloaded (what you did), the DT
> > overlay is re-applied, which causes the reset controller
> > (reset-microchip-sparx5) to re-probe. During probe, it performs a GCB soft reset
> > that resets the switch core, but protects the CPU domain from the reset. The
> > FDMA engine is part of the CPU domain, so it is not reset.
> >
> > This leaves the switch core in a reset state while the FDMA
> > retains state from the previous driver instance. When the switch driver
> > subsequently probes and activates the FDMA channels, the two are out of
> > sync, and the FDMA immediately reports extraction errors.
> >
> > Theres actually an FDMA register called NRESET that resets the FDMA controller
> > state. Calling this in the FDMA init path causes traffic to work correctly on
> > lan966x_pci reload, but it does not get rid of the FDMA splats you posted above.
> > They get queued up between the switch core reset, in the reset controller, and
> > the FDMA enabling. I tried different approaches to drain or flush queues, but
> > they wont go away entirely.
> >
> > The only thing that seems to work consistently is to *not* do the soft reset in
> > the reset controller for the PCI path. The soft reset is actually the problem:
> > it only resets the switch core while protecting the CPU domain (including FDMA),
> > causing a desync.
> >
> > A simple fix could be (in reset-microchip-sparx5.c):
> >
> > +static bool mchp_reset_is_pci(struct device *dev)
> > +{
> > +     for (dev = dev->parent; dev; dev = dev->parent) {
> > +             if (dev_is_pci(dev))
> > +                     return true;
> > +     }
> > +     return false;
> > +}
> >
> > -     /* Issue the reset very early, our actual reset callback is a noop. */
> > -     err = sparx5_switch_reset(ctx);
> > -     if (err)
> > -             return err;
> > +     /* Issue the reset very early, our actual reset callback is a noop.
> > +      *
> > +      * On the PCI path, skip the reset. The endpoint is already in
> > +      * power-on reset state on the first probe. On subsequent probes
> > +      * (after driver reload), resetting the switch core while the FDMA
> > +      * retains state (CPU domain is protected from the soft reset)
> > +      * causes the two to go out of sync, leading to FDMA extraction
> > +      * errors.
> > +      */
> > +     if (!mchp_reset_is_pci(&pdev->dev)) {
> > +             err = sparx5_switch_reset(ctx);
> > +             if (err)
> > +                     return err;
> > +     }
> >
> > Could you test it and see if it helps the problem on your side.
> >
> 
> I have tested it on my ARM and x86 system. It fixes the lan966x_pci module
> unloading / reloading issue.
> 
> However an other regression is present. After a reboot, without power
> off/on, the board is not working (tested on both my ARM and x86 systems).
> 
> According to your explanation, this makes sense.
> 
> IMHO, the problem is that we cannot make the assumption that "The endpoint
> is already in power-on reset state on the first probe". That's not true
> when you just call the reboot command.
> 
> Best regards,
> Hervé

Again, thanks for testing.

Agreed, that makes sense.

I will continue experimenting with the FDMA reset and see if I can do an FDMA
reset on switch driver probe, while not getting any intermediate FDMA errors.
After spring break, that is :)

/Daniel



^ permalink raw reply

* Re: [PATCH net] bridge: cfm: do not reschedule TX work when interval is zero
From: Simon Horman @ 2026-03-27 11:20 UTC (permalink / raw)
  To: Xiang Mei
  Cc: netdev, bridge, razor, idosch, davem, edumazet, pabeni, bestswngs
In-Reply-To: <20260326031957.3299500-1-xmei5@asu.edu>

On Wed, Mar 25, 2026 at 08:19:57PM -0700, Xiang Mei wrote:
> ccm_tx_work_expired() uses interval_to_us() to convert the configured
> exp_interval enum into a microsecond delay, then passes it to
> queue_delayed_work() to schedule the next iteration. The ccm_tx_dwork
> callback re-arms the same delayed_work struct at the end of each
> invocation, forming a repeating timer.
> 
> interval_to_us() returns 0 for BR_CFM_CCM_INTERVAL_NONE and any
> out-of-range enum value. When this 0 is passed to queue_delayed_work()
> as the delay, the work item fires immediately and re-arms itself with
> zero delay again, creating an infinite tight loop. Each iteration
> allocates an skb via ccm_frame_build() and queues it for transmission.
> The skbs pile up faster than the network stack can free them because the
> worker never yields the CPU, rapidly exhausting all kernel memory until
> OOM deadlock panic.
> 
> Since CC config and CCM TX are independent netlink commands that can be
> issued in any order, there is no single configuration entry point where
> rejecting interval=0 would cover all cases.
> 
> Fix this by checking the interval at the start of ccm_tx_work_expired()
> and stopping transmission immediately if it is zero. Set period to 0 so
> that br_cfm_cc_ccm_tx() correctly sees transmission as stopped and can
> restart it later if a valid interval is configured. This also avoids
> transmitting a CCM frame with an invalid interval value.

Hi,

I think that the principle should be that code that doesn't need
to be in the datapath shouldn't be in the datapath.

So, with that in mind, I think it would be better to set a lower bound on
exp_interval when the mep is:

a) Created. It looks like that happens in br_cfm_mep_create
b) Configured. It looks like that can be done by setting a policy on the
   minimum value of IFLA_BRIDGE_CFM_CC_CONFIG_EXP_INTERVAL

> 
> Fixes: a806ad8ee2aa ("bridge: cfm: Kernel space implementation of CFM. CCM frame TX added.")
> Reported-by: Weiming Shi <bestswngs@gmail.com>
> Signed-off-by: Xiang Mei <xmei5@asu.edu>

...

^ permalink raw reply

* Re: [PATCH net-next v4] selftests: net: add tests for PPP
From: Guillaume Nault @ 2026-03-27 11:28 UTC (permalink / raw)
  To: Qingfang Deng
  Cc: Sebastian Andrzej Siewior, Shuah Khan, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
	Felix Maurer, Antonio Quartulli, linux-kernel, linux-kselftest,
	linux-ppp, netdev, Paul Mackerras
In-Reply-To: <CALW65jYdzn_rZWa2zwYd5J+Gd=kyaGMsVFyX0fMJfKfgULMO6w@mail.gmail.com>

On Thu, Mar 26, 2026 at 04:26:23PM +0800, Qingfang Deng wrote:
> Hi Sebastian,
> 
> On Thu, Mar 26, 2026 at 4:13 PM Sebastian Andrzej Siewior
> <bigeasy@linutronix.de> wrote:
> >
> > On 2026-03-26 10:16:24 [+0800], Qingfang Deng wrote:
> > > Add ping and iperf3 tests for ppp_async.c and pppoe.c.
> >
> > Oh thank you for doing this.
> > I haven't look in detail but this cover the "invalid loop" cases that
> > ppp tries to catch?
> 
> By "invalid loop", do you mean transmit recursion?
> https://lore.kernel.org/all/20250715150806.700536-2-bigeasy@linutronix.de/
> 
> AFAIK, this can only happen with PPTP or L2TP, which were not included
> in this patch.

The problem was originally reproduced using L2TP, indeed. But I guess
that it could also be reproduced with PPPoE by using a UDP tunnel
device like VXLAN (like sending a packet through a PPP interface,
handled by PPPoE, running on top of a VXLAN device, that routes the UDP
encapsulated packet back to the original PPP interface).

> Add Cc: Guillaume Nault
> 
> 
> Regards,
> Qingfang
> 


^ permalink raw reply

* Re: [PATCH v5 phy-next 10/27] scsi: ufs: qcom: keep parallel track of PHY power state
From: Vladimir Oltean @ 2026-03-27 11:28 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: linux-phy, Vinod Koul, Neil Armstrong, dri-devel, freedreno,
	linux-arm-kernel, linux-arm-msm, linux-can, linux-gpio, linux-ide,
	linux-kernel, linux-media, linux-pci, linux-renesas-soc,
	linux-riscv, linux-rockchip, linux-samsung-soc, linux-scsi,
	linux-sunxi, linux-tegra, linux-usb, netdev, spacemit,
	UNGLinuxDriver, James E.J. Bottomley, Martin K. Petersen,
	Nitin Rawat
In-Reply-To: <gq4sswslkjaoe5hhxe2mz6z57uiumotqknkryadvfsstj4srx4@qgenqekgrqv4>

[-- Attachment #1: Type: text/plain, Size: 1960 bytes --]

On Fri, Mar 27, 2026 at 12:22:46PM +0530, Manivannan Sadhasivam wrote:
> I tested the patch. But it fails ufs_qcom_power_up_sequence() if PHY was already
> powered on:
> 
> [   31.513321] qcom-qmp-ufs-phy 1d87000.phy: phy initialization timed-out
> [   31.513335] ufshcd-qcom 1d84000.ufshc: Failed to calibrate PHY: -110
> [   31.565273] ufshcd-qcom 1d84000.ufshc: Enabling the controller failed
> 
> Funny thing is, it didn't affect the functionality since the UFS core retries
> ufshcd_hba_enable() and in the error path of ufs_qcom_power_up_sequence(),
> phy_power_off() gets called and that causes the next try to succeed. So it is
> evident that, if PHY was already powered ON, it should be powered off before
> ufs_qcom_phy_power_on(). And due to the UFS driver design,
> ufs_qcom_power_up_sequence() can get called multiple times. So we cannot just
> remove phy_power_off().
> 
> Below diff on top of your patch fixes the issue:
> 
> ```
> diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
> index ed067247d72a..2c9fe03f349e 100644
> --- a/drivers/ufs/host/ufs-qcom.c
> +++ b/drivers/ufs/host/ufs-qcom.c
> @@ -567,6 +567,8 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
>         if (ret)
>                 return ret;
>  
> +       ufs_qcom_phy_power_off(host);
> +
>         ret = ufs_qcom_phy_set_gear(host, mode);
>         if (ret) {
>                 dev_err(hba->dev, "%s: phy_set_mode_ext() failed, ret = %d\n",
> ```
> 
> - Mani

Understood. Thanks for testing.

I'm still not satisfied with this level of complexity. If I get you
right, ufs_qcom_phy_power_off() is still needed because phy_calibrate()
expects a "fresh after power on" state, otherwise it fails? That would
be the second reason, apart from the first one I already identified
(undo a phy_power_on() done prior to phy_init()).

If so, could you please test the 3 patches attached (no relationship
with anything else we've exchanged thus far)?

[-- Attachment #2: 0001-phy-qcom-qmp-ufs-support-dynamic-gear-changing.patch --]
[-- Type: text/x-diff, Size: 2013 bytes --]

From 2d42c2d40e6ddfd0c73fc39601f93f7b81a42401 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Fri, 27 Mar 2026 12:41:00 +0200
Subject: [PATCH 1/3] phy: qcom-qmp-ufs: support dynamic gear changing

Currently, phy_set_mode_ext() on the QMP UFS PHY expects the PHY to be
powered down, and it makes no change to the hardware state, instead
phy_power_on() followed by phy_calibrate() must be run afterwards.

"Order of API calls" from Documentation/driver-api/phy/phy.rst has a
roundabout and not really clear way of saying that both calling
sequences should be supported. This was further discussed here,
documentation is pending an update:
https://lore.kernel.org/linux-phy/E1vo0mF-00000007kbg-1OeA@rmk-PC.armlinux.org.uk/

By absorbing the phy_power_off() -> ... -> phy_power_on() ->
phy_configure() surrounding sequence into phy_set_mode_ext(), consumer
drivers can be greatly simplified, and we also have a proper
self-standing phy_set_mode_ext() implementation which does not rely on
other calls to do its job.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index df138a5442eb..e75b059bf246 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -2004,15 +2004,24 @@ static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)
 {
 	struct qmp_ufs *qmp = phy_get_drvdata(phy);
 	const struct qmp_phy_cfg *cfg = qmp->cfg;
+	bool powered_on = phy->power_count;
 
 	if (submode > cfg->max_supported_gear || submode == 0) {
 		dev_err(qmp->dev, "Invalid PHY submode %d\n", submode);
 		return -EINVAL;
 	}
 
+	if (powered_on)
+		qmp_ufs_power_off(phy);
+
 	qmp->mode = mode;
 	qmp->submode = submode;
 
+	if (powered_on) {
+		qmp_ufs_power_on(phy);
+		return qmp_ufs_phy_calibrate(phy);
+	}
+
 	return 0;
 }
 
-- 
2.34.1


[-- Attachment #3: 0002-scsi-ufs-qcom-call-phy_init-before-phy_power_on.patch --]
[-- Type: text/x-diff, Size: 3707 bytes --]

From 8d156781d38597865da37a86417f553143d74eaa Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Fri, 27 Mar 2026 13:14:39 +0200
Subject: [PATCH 2/3] scsi: ufs: qcom: call phy_init() before phy_power_on()

The Qualcomm UFS host controller driver violates the Generic PHY API
expectation, documented in section "Order of API calls" from
Documentation/driver-api/phy/phy.rst, and then tries to hide it.

The expectation is that calls must be made in the phy_init() ->
phy_power_on() -> phy_power_off() -> phy_exit() sequence.

What we actually have is:

ufshcd_init()
-> ufshcd_hba_init()
   -> ufshcd_setup_clocks(hba, true)
      -> ufshcd_vops_setup_clocks(hba, true, POST_CHANGE)
         -> ufs_qcom_setup_clocks(hba, true, POST_CHANGE)
            -> phy_power_on(phy)
   -> ufshcd_variant_hba_init()
      -> ufs_qcom_init()
         -> ufs_qcom_setup_clocks(hba, true, POST_CHANGE)
            -> phy_power_on(phy)
-> ufshcd_hba_enable()
   -> ufshcd_vops_hce_enable_notify()
      -> ufs_qcom_hce_enable_notify()
         -> ufs_qcom_power_up_sequence()
            -> if (phy->power_count) phy_power_off(phy)
            -> phy_init(phy)

This "works" because the way that the "phy_power_on was called before
phy_init\n" condition is detected in phy-core.c is if the power_count is
positive at the phy_init() call time.

By having that "if (phy->power_count) phy_power_off(phy)" logic, the
ufs-qcom.c technically sidesteps the test, but actually violates the
Generic PHY API even more (calls phy_power_on() *and* phy_power_off()
before phy_init()).

The reason why I stumbled upon this was that I was trying to remove
dereferences of phy->power_count from drivers. This is a PHY-internal
field, and using it from drivers is highly likely to be incorrect, as
this case showcases rather well.

As commit 77d2fa54a945 ("scsi: ufs: qcom : Refactor phy_power_on/off
calls") shows, this driver tries to couple the PHY power state with the
HBA clocks, for power saving reasons. I won't try to change that, I will
just move the phy_init() call earlier, to ufs_qcom_init().

After the phy_init() movement, ufs_qcom_power_up_sequence() should no
longer need to do either phy_init() nor the conditional phy_power_off().
However, phy_power_off() is still needed, for a separate reason which
will be dealt with separately.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Nitin Rawat <quic_nitirawa@quicinc.com>

v5->v6: rewrite after actually understanding the core issue
v4->v5: patch is new
---
 drivers/ufs/host/ufs-qcom.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index 375fd24ba458..ffa70c6c7143 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -513,13 +513,6 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
 
 
 	/* phy initialization - calibrate the phy */
-	ret = phy_init(phy);
-	if (ret) {
-		dev_err(hba->dev, "%s: phy init failed, ret = %d\n",
-			__func__, ret);
-		return ret;
-	}
-
 	ret = phy_set_mode_ext(phy, mode, host->phy_gear);
 	if (ret)
 		goto out_disable_phy;
@@ -1441,6 +1434,13 @@ static int ufs_qcom_init(struct ufs_hba *hba)
 	if (err)
 		goto out_variant_clear;
 
+	err = phy_init(host->generic_phy);
+	if (err) {
+		dev_err(hba->dev, "%s: phy_init failed, ret = %d\n",
+			__func__, err);
+		goto out_variant_clear;
+	}
+
 	ufs_qcom_setup_clocks(hba, true, POST_CHANGE);
 
 	ufs_qcom_get_default_testbus_cfg(host);
-- 
2.34.1


[-- Attachment #4: 0003-scsi-ufs-qcom-make-use-of-QMP-PHY-dynamic-gear-switc.patch --]
[-- Type: text/x-diff, Size: 1696 bytes --]

From 88f4bdfee770cd433a940a14e318d8c8b5dfa516 Mon Sep 17 00:00:00 2001
From: Vladimir Oltean <vladimir.oltean@nxp.com>
Date: Fri, 27 Mar 2026 13:18:05 +0200
Subject: [PATCH 3/3] scsi: ufs: qcom: make use of QMP PHY dynamic gear
 switching ability

The QMP UFS PHY can now tolerate having phy_set_mode_ext() being called
while the PHY is powered up. We no longer need to power it down, back up
and calibrate it.

Simplify ufs_qcom_power_up_sequence() by relying on just phy_set_mode_ext()
and let PHY power management be handled just by ufs_qcom_setup_clocks().

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
 drivers/ufs/host/ufs-qcom.c | 25 +------------------------
 1 file changed, 1 insertion(+), 24 deletions(-)

diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index ffa70c6c7143..cf7b67f2021e 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -508,37 +508,14 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
 	if (ret)
 		return ret;
 
-	if (phy->power_count)
-		phy_power_off(phy);
-
-
 	/* phy initialization - calibrate the phy */
 	ret = phy_set_mode_ext(phy, mode, host->phy_gear);
 	if (ret)
-		goto out_disable_phy;
-
-	/* power on phy - start serdes and phy's power and clocks */
-	ret = phy_power_on(phy);
-	if (ret) {
-		dev_err(hba->dev, "%s: phy power on failed, ret = %d\n",
-			__func__, ret);
-		goto out_disable_phy;
-	}
-
-	ret = phy_calibrate(phy);
-	if (ret) {
-		dev_err(hba->dev, "Failed to calibrate PHY: %d\n", ret);
-		goto out_disable_phy;
-	}
+		return ret;
 
 	ufs_qcom_select_unipro_mode(host);
 
 	return 0;
-
-out_disable_phy:
-	phy_exit(phy);
-
-	return ret;
 }
 
 /*
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH 0/4] net: bridge: mcast: add multicast exponential field encoding
From: Nikolay Aleksandrov @ 2026-03-27 11:31 UTC (permalink / raw)
  To: Ujjal Roy, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Ido Schimmel, David Ahern
  Cc: Ujjal Roy, bridge, netdev, linux-kernel
In-Reply-To: <0e8a01b0-9b83-405f-a0ad-7b335135962f@blackwall.org>

On 27/03/2026 08:41, Nikolay Aleksandrov wrote:
> On 26/03/2026 17:07, Ujjal Roy wrote:
>> Description:
>> This series addresses a mismatch in how multicast query
>> intervals and response codes are handled across IPv4 (IGMPv3)
>> and IPv6 (MLDv2). While decoding logic currently exists,
>> the corresponding encoding logic is missing during query
>> packet generation. This leads to incorrect intervals being
>> transmitted when values exceed their linear thresholds.
>>
>> The patches introduce a unified floating-point encoding
>> approach based on RFC3376 and RFC3810, ensuring that large
>> intervals are correctly represented in QQIC and MRC fields
>> using the exponent-mantissa format.
>>
>> Key Changes:
>> * ipv4: igmp: get rid of IGMPV3_{QQIC,MRC} and simplify calculation
>>    Removes legacy macros in favor of a cleaner, unified
>>    calculation for retrieving intervals from encoded fields,
>>    improving code maintainability.
>>
>> * ipv6: mld: rename mldv2_mrc() and add mldv2_qqi()
>>    Standardizes MLDv2 terminology by renaming mldv2_mrc()
>>    to mldv2_mrd() (Maximum Response Delay) and introducing
>>    a new API mldv2_qqi for QQI calculation, improving code
>>    readability.
>>
>> * ipv4: igmp: encode multicast exponential fields
>>    Introduces the logic to dynamically calculate the exponent
>>    and mantissa using bit-scan (fls). This ensures QQIC and
>>    MRC fields (8-bit) are properly encoded when transmitting
>>    query packets with intervals that exceed their respective
>>    linear threshold value of 128 (for QQI/MRT).
>>
>> * ipv6: mld: encode multicast exponential fields
>>    Applies similar encoding logic for MLDv2. This ensures
>>    QQIC (8-bit) and MRC (16-bit) fields are properly encoded
>>    when transmitting query packets with intervals that exceed
>>    their respective linear thresholds (128 for QQI; 32768
>>    for MRD).
>>
>> Impact:
>> These changes ensure that multicast queriers and listeners
>> stay synchronized on timing intervals, preventing protocol
>> timeouts or premature group membership expiration caused
>> by incorrectly formatted packet headers.
>>
> 
> Can you add selftests which cover these cases?
> 
> 

Forgot to mention - for improvements and new features please target net-next.

Cheers,
  Nik


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox