lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <40d030d5-8d30-41b7-ae86-8baae6f594c5@intel.com>
Date: Mon, 16 Dec 2024 06:38:31 +0100
From: Przemek Kitszel <przemyslaw.kitszel@...el.com>
To: Michal Schmidt <mschmidt@...hat.com>
CC: <netdev@...r.kernel.org>, Arkadiusz Kubalewski
	<arkadiusz.kubalewski@...el.com>, Karol Kolacinski
	<karol.kolacinski@...el.com>, Tony Nguyen <anthony.l.nguyen@...el.com>,
	Miroslav Lichvar <mlichvar@...hat.com>, <intel-wired-lan@...ts.osuosl.org>
Subject: Re: [PATCH iwl-next 2/3] ice: lower the latency of GNSS reads

On 12/12/24 16:34, Michal Schmidt wrote:
> The E810 is connected to the u-blox GNSS module over I2C. The ice driver
> periodically (every ~20ms) sends AdminQ commands to poll the u-blox for
> available data. Most of the time, there's no data. When the u-blox
> finally responds that data is available, usually it's around 800 bytes.
> It can be more or less, depending on how many NMEA messages were
> configured using ubxtool. ice then proceeds to read all the data.
> AdminQ and I2C are slow. The reading is performed in chunks of 15 bytes.
> ice reads all of the data before passing it to the kernel GNSS subsystem
> and onwards to userspace.
> 
> Improve the NMEA message receiving latency. Pass each 15-bytes chunk to
> userspace as soon as it's received.
> 

Thank you, overall it makes a good addition!
Please find some review feedback below.

> Tested-by: Miroslav Lichvar <mlichvar@...hat.com>
> Signed-off-by: Michal Schmidt <mschmidt@...hat.com>
> ---
>   drivers/net/ethernet/intel/ice/ice_gnss.c | 29 +++++++----------------
>   drivers/net/ethernet/intel/ice/ice_gnss.h |  6 ++++-
>   2 files changed, 14 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c
> index 9b1f970f4825..7922311d2545 100644
> --- a/drivers/net/ethernet/intel/ice/ice_gnss.c
> +++ b/drivers/net/ethernet/intel/ice/ice_gnss.c
> @@ -88,10 +88,10 @@ static void ice_gnss_read(struct kthread_work *work)
>   	unsigned long delay = ICE_GNSS_POLL_DATA_DELAY_TIME;
>   	unsigned int i, bytes_read, data_len, count;
>   	struct ice_aqc_link_topo_addr link_topo;
> +	char buf[ICE_MAX_I2C_DATA_SIZE];
>   	struct ice_pf *pf;
>   	struct ice_hw *hw;
>   	__be16 data_len_b;
> -	char *buf = NULL;
>   	u8 i2c_params;
>   	int err = 0;
>   
> @@ -121,16 +121,6 @@ static void ice_gnss_read(struct kthread_work *work)
>   		goto requeue;
>   
>   	/* The u-blox has data_len bytes for us to read */
> -
> -	data_len = min_t(typeof(data_len), data_len, PAGE_SIZE);

prior to your patch, the buffer is too small when there is more than
PAGE_SIZE bytes to read, that warrants sending it as -net
There is not that much code here, and with your description it is easy
to follow, and the change is really "atomic" (send out each time instead
of just once at the end), no refactors, so feels nice for -net IMO.

> -
> -	buf = (char *)get_zeroed_page(GFP_KERNEL);
> -	if (!buf) {
> -		err = -ENOMEM;
> -		goto requeue;
> -	}
> -
> -	/* Read received data */
>   	for (i = 0; i < data_len; i += bytes_read) {
>   		unsigned int bytes_left = data_len - i;
>   
> @@ -139,19 +129,18 @@ static void ice_gnss_read(struct kthread_work *work)
>   
>   		err = ice_aq_read_i2c(hw, link_topo, ICE_GNSS_UBX_I2C_BUS_ADDR,
>   				      cpu_to_le16(ICE_GNSS_UBX_EMPTY_DATA),
> -				      bytes_read, &buf[i], NULL);
> +				      bytes_read, buf, NULL);
>   		if (err)
> -			goto free_buf;
> +			goto requeue;
> +
> +		count = gnss_insert_raw(pf->gnss_dev, buf, bytes_read);
> +		if (count != bytes_read)

Before there was nothing to do on this condition, but now it's in the
loop, so I would expect to either break or retry or otherwise recover
here. Just going with the next step of the loop when you have lost some
bytes feels wrong. Not sure how much about that case is theoretical,
perhaps API could be fixed instead.

> +			dev_dbg(ice_pf_to_dev(pf),

in case of v2, I would squash the first commit here, an "additional
paragraph" would be enough

> +				"gnss_insert_raw ret=%d size=%d\n",
> +				count, bytes_read);
>   	}
>   
> -	count = gnss_insert_raw(pf->gnss_dev, buf, i);
> -	if (count != i)
> -		dev_dbg(ice_pf_to_dev(pf),
> -			"gnss_insert_raw ret=%d size=%d\n",
> -			count, i);
>   	delay = ICE_GNSS_TIMER_DELAY_TIME;
> -free_buf:
> -	free_page((unsigned long)buf);
>   requeue:
>   	kthread_queue_delayed_work(gnss->kworker, &gnss->read_work, delay);
>   	if (err)
> diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.h b/drivers/net/ethernet/intel/ice/ice_gnss.h
> index 15daf603ed7b..e0e939f1b102 100644
> --- a/drivers/net/ethernet/intel/ice/ice_gnss.h
> +++ b/drivers/net/ethernet/intel/ice/ice_gnss.h
> @@ -8,7 +8,11 @@
>   #define ICE_GNSS_POLL_DATA_DELAY_TIME	(HZ / 50) /* poll every 20 ms */
>   #define ICE_GNSS_TIMER_DELAY_TIME	(HZ / 10) /* 0.1 second per message */
>   #define ICE_GNSS_TTY_WRITE_BUF		250
> -#define ICE_MAX_I2C_DATA_SIZE		FIELD_MAX(ICE_AQC_I2C_DATA_SIZE_M)
> +/* ICE_MAX_I2C_DATA_SIZE is FIELD_MAX(ICE_AQC_I2C_DATA_SIZE_M).
> + * However, FIELD_MAX() does not evaluate to an integer constant expression,
> + * so it can't be used for the size of a non-VLA array.
> + */
> +#define ICE_MAX_I2C_DATA_SIZE		15

static_assert() is better than doc to say that two values are the same

>   #define ICE_MAX_I2C_WRITE_BYTES		4
>   
>   /* u-blox ZED-F9T specific definitions */


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ