Skip to content

Commit 7263f64

Browse files
vladimirolteankuba-moo
authored andcommitted
lib: packing: add pack() and unpack() wrappers over packing()
Geert Uytterhoeven described packing() as "really bad API" because of not being able to enforce const correctness. The same function is used both when "pbuf" is input and "uval" is output, as in the other way around. Create 2 wrapper functions where const correctness can be ensured. Do ugly type casts inside, to be able to reuse packing() as currently implemented - which will _not_ modify the input argument. Also, take the opportunity to change the type of startbit and endbit to size_t - an unsigned type - in these new function prototypes. When int, an extra check for negative values is necessary. Hopefully, when packing() goes away completely, that check can be dropped. My concern is that code which does rely on the conditional directionality of packing() is harder to refactor without blowing up in size. So it may take a while to completely eliminate packing(). But let's make alternatives available for those who do not need that. Link: https://lore.kernel.org/netdev/20210223112003.2223332-1-geert+renesas@glider.be/ Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://patch.msgid.link/20241002-packing-kunit-tests-and-split-pack-unpack-v2-4-8373e551eae3@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 816ad8f commit 7263f64

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

include/linux/packing.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,10 @@ enum packing_op {
2020
int packing(void *pbuf, u64 *uval, int startbit, int endbit, size_t pbuflen,
2121
enum packing_op op, u8 quirks);
2222

23+
int pack(void *pbuf, const u64 *uval, size_t startbit, size_t endbit,
24+
size_t pbuflen, u8 quirks);
25+
26+
int unpack(const void *pbuf, u64 *uval, size_t startbit, size_t endbit,
27+
size_t pbuflen, u8 quirks);
28+
2329
#endif

lib/packing.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ static int calculate_box_addr(int box, size_t len, u8 quirks)
9090
* @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and
9191
* QUIRK_MSB_ON_THE_RIGHT.
9292
*
93+
* Note: this is deprecated, prefer to use pack() or unpack() in new code.
94+
*
9395
* Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming
9496
* correct usage, return code may be discarded.
9597
* If op is PACK, pbuf is modified.
@@ -216,4 +218,56 @@ int packing(void *pbuf, u64 *uval, int startbit, int endbit, size_t pbuflen,
216218
}
217219
EXPORT_SYMBOL(packing);
218220

221+
/**
222+
* pack - Pack u64 number into bitfield of buffer.
223+
*
224+
* @pbuf: Pointer to a buffer holding the packed value.
225+
* @uval: Pointer to an u64 holding the unpacked value.
226+
* @startbit: The index (in logical notation, compensated for quirks) where
227+
* the packed value starts within pbuf. Must be larger than, or
228+
* equal to, endbit.
229+
* @endbit: The index (in logical notation, compensated for quirks) where
230+
* the packed value ends within pbuf. Must be smaller than, or equal
231+
* to, startbit.
232+
* @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf.
233+
* @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and
234+
* QUIRK_MSB_ON_THE_RIGHT.
235+
*
236+
* Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming
237+
* correct usage, return code may be discarded. The @pbuf memory will
238+
* be modified on success.
239+
*/
240+
int pack(void *pbuf, const u64 *uval, size_t startbit, size_t endbit,
241+
size_t pbuflen, u8 quirks)
242+
{
243+
return packing(pbuf, (u64 *)uval, startbit, endbit, pbuflen, PACK, quirks);
244+
}
245+
EXPORT_SYMBOL(pack);
246+
247+
/**
248+
* unpack - Unpack u64 number from packed buffer.
249+
*
250+
* @pbuf: Pointer to a buffer holding the packed value.
251+
* @uval: Pointer to an u64 holding the unpacked value.
252+
* @startbit: The index (in logical notation, compensated for quirks) where
253+
* the packed value starts within pbuf. Must be larger than, or
254+
* equal to, endbit.
255+
* @endbit: The index (in logical notation, compensated for quirks) where
256+
* the packed value ends within pbuf. Must be smaller than, or equal
257+
* to, startbit.
258+
* @pbuflen: The length in bytes of the packed buffer pointed to by @pbuf.
259+
* @quirks: A bit mask of QUIRK_LITTLE_ENDIAN, QUIRK_LSW32_IS_FIRST and
260+
* QUIRK_MSB_ON_THE_RIGHT.
261+
*
262+
* Return: 0 on success, EINVAL or ERANGE if called incorrectly. Assuming
263+
* correct usage, return code may be discarded. The @uval will be
264+
* modified on success.
265+
*/
266+
int unpack(const void *pbuf, u64 *uval, size_t startbit, size_t endbit,
267+
size_t pbuflen, u8 quirks)
268+
{
269+
return packing((void *)pbuf, uval, startbit, endbit, pbuflen, UNPACK, quirks);
270+
}
271+
EXPORT_SYMBOL(unpack);
272+
219273
MODULE_DESCRIPTION("Generic bitfield packing and unpacking");

0 commit comments

Comments
 (0)