netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jacob Keller <jacob.e.keller@intel.com>
To: Vladimir Oltean <olteanv@gmail.com>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>
Subject: lib/packing.c behaving weird if buffer length is not multiple of 4 with QUIRK_LSW32_IS_FIRST
Date: Thu, 15 Aug 2024 14:16:13 -0700	[thread overview]
Message-ID: <a0338310-e66c-497c-bc1f-a597e50aa3ff@intel.com> (raw)

Hi Vladimir!

I am recently attempting to refactor some bespoke code for packing data
in the ice networking driver into a bit packed hardware array, using the
<linux/packing.h> and lib/packing.c infrastructure.

My hardware packed buffer needs QUIRK_LITTLE_ENDIAN and
QUIRK_LSW32_IS_FIRST, as the entire buffer is packed as little endian,
and the lower words come first in the buffer.

Everything was working ok in initial testing, until I tried packing a
buffer that was 22 bytes long. Everything seemed to shift by 2 bytes:

Here, I print the initial details such as offset, lsb, width, then the
hex dump of the u64 value I'm trying to insert.

I do the call to packing() with the appropriate quirks set, and then hex
dump the 22-byte buffer after.

> kernel: offset=0, size=8, lsb=0, width=57
> kernel: value: 60 9b fe 01 00 00 00 00
> kernel: 0x0000000001fe9b60 -> 000-056: fe 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> kernel: 0x0000000001fe9b60 -> 000-056: 00 00 00 00 00 00

It seems to have failed to copy the first two bytes in to the buffer.

I discovered that if I pretend the buffer is 24 bytes (a multiple of 4
bytes, i.e. a word size), then everything works as expected:

> kernel: offset=0, size=8, lsb=0, width=57
> kernel: value: 60 fc fe 01 00 00 00 00
> kernel: 0x0000000001fefc60 -> 000-056: 60 fc fe 01 00 00 00 00 00 00 00 00 00 00 00 00
> kernel: 0x0000000001fefc60 -> 000-056: 00 00 00 00 00 00 00 00

It seems like this is either a misunderstanding of a fundamental
requirement of the packing() infrastructure, a bug in the
QUIRK_LSW32_IS_FIRST, or I need a new quirk for the packing infrastructure?

Essentially, I think the problem is that it uses the length of the
buffer to find the word, but when the length is not a multiple of 2, the
word offset picked is incorrect.

Using a larger length than the size of the buffer "works" as long as I
never use a bit offset thats larger than the *actual* buffer.. but that
seems like a poor solution.

Essentially, it seems like the default indexing for big endian is
searching for each byte from the end of the array and then using the
quirks to swap back to the inverse ending.

I think the fix is probably just to do a round-up division on the len/4
check in get_reverse_lsw32_offset, since its calculating the total
number of words in the length, and effectively rounds down for lengths
that aren't multiples of 4.

Does this seem like the correct analysis to you?

Thanks,
Jake

             reply	other threads:[~2024-08-15 21:16 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-15 21:16 Jacob Keller [this message]
2024-08-16 23:37 ` lib/packing.c behaving weird if buffer length is not multiple of 4 with QUIRK_LSW32_IS_FIRST Jacob Keller
2024-08-18 13:29   ` Vladimir Oltean
2024-08-19 18:45     ` Jacob Keller
2024-08-19 21:53       ` Jacob Keller
2024-08-21 13:58         ` Vladimir Oltean
2024-08-21 19:12           ` Jacob Keller
2024-08-21 20:21             ` Vladimir Oltean
2024-08-21 23:41               ` Jacob Keller
2024-08-23  1:41                 ` Jacob Keller
2024-08-23 19:53                   ` Jacob Keller
2024-08-26 22:03                     ` Jacob Keller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a0338310-e66c-497c-bc1f-a597e50aa3ff@intel.com \
    --to=jacob.e.keller@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).