<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Tue, Nov 10, 2026 at 3:21 PM Konstantin Ananyev <<a href="mailto:konstantin.v.ananyev@yandex.ru">konstantin.v.ananyev@yandex.ru</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
<br>
><br>
><br>
> On Mon, Nov 9, 2026 at 3:40 PM Konstantin Ananyev <br>
> <<a href="mailto:konstantin.v.ananyev@yandex.ru" target="_blank">konstantin.v.ananyev@yandex.ru</a>> wrote:<br>
><br>
><br>
> > Replace the __m128i members in the PCLMULQDQ CRC context with<br>
> aligned<br>
> > uint64_t arrays to allow portable compile-time initialization.<br>
> ><br>
> > Move CRC16-CCITT and CRC32-ETH folding constants into static<br>
> const context<br>
> > structures in their respective handlers, removing the runtime<br>
> > initialization previously performed by rte_net_crc_sse42_init<br>
> and avoids<br>
> > the extra data segment static variables which were being populated.<br>
> ><br>
> > Load the constants into SIMD registers using aligned loads when<br>
> performing<br>
> > CRC calculations. This was done transparently previously when the<br>
> > __m128i values were assigned, now there is explicit SIMD load done.<br>
><br>
> It is not clear why(how) new code is better then what we have<br>
> right now.<br>
> Can you probably provide a bit more details?<br>
><br>
><br>
> Previously this file was maintaining static variables in data segment <br>
> namely:<br>
> static alignas(16) struct crc_pclmulqdq_ctx crc32_eth_pclmulqdq;<br>
> static alignas(16) struct crc_pclmulqdq_ctx crc16_ccitt_pclmulqdq;<br>
><br>
> These were populated in the init function with the same calculated <br>
> fold constants.<br>
> The constants already are present in the rodata section in the binary.<br>
> Hence the init is doing extra work in copying it over to the <br>
> static crc_pclmulqdq_ctx<br>
> structures which is redundant.<br>
><br>
> This patch avoids this extra copy during init and modifies the SIMD <br>
> routines<br>
> to directly read the constants from rodata memory. Thus the data <br>
> segment memory usage is<br>
> reduced by getting rid of the static variables (128 bytes). There <br>
> should be no<br>
> performance impact by this change (minus the init work done previously).<br>
<br>
TBH, it looks to me like a nitpicking: yes we move 128B from .data to <br>
.rodata, but in terms<br>
of functionality or perfomance - does it really matter?<br></blockquote><div><br></div><div>It is not moving from .data to .rodata, same data was already there in .rodata,</div><div>hence it is removal from .data.</div><div><br></div><div>Well this was mainly motivated from the rewrite for improving barrett reduction.</div><div>I've combined this in the other patch and we can drop this patch from review.</div><div>Kindly review the newer submission which includes this refactory change as well:</div><div><a href="https://patches.dpdk.org/project/dpdk/patch/20261110121048.831330-1-16567adigashreesh@gmail.com/">https://patches.dpdk.org/project/dpdk/patch/20261110121048.831330-1-16567adigashreesh@gmail.com/</a></div><div><br></div><div>Thanks,</div><div>Shreesh</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Though yes, the code looks a bit simpler and nicer.<br>
If we decided to improve the init code, then my preference would be to <br>
use rte_xmm_t?<br>
Then we can do something like that:<br>
struct crc_pclmulqdq_ctx {<br>
rte_xmm_t rk1_rk2;<br>
...<br>
};<br>
...<br>
static const struct crc_pclmulqdq_ctx crc32_eth_pclmulqdq = {<br>
.rk1_rk2 = { .u64 = {0x1c6e41596LLU, 0x154442bd4LLU }},<br>
...<br>
};<br>
...<br>
__m128i k = params->rk3_rk4.x;<br>
<br>
><br>
> ><br>
> > Signed-off-by: Shreesh Adiga <<a href="mailto:16567adigashreesh@gmail.com" target="_blank">16567adigashreesh@gmail.com</a>><br>
> > ---<br>
> > lib/net/net_crc_sse.c | 68<br>
> ++++++++++++++-----------------------------<br>
> > 1 file changed, 22 insertions(+), 46 deletions(-)<br>
> ><br>
> > diff --git a/lib/net/net_crc_sse.c b/lib/net/net_crc_sse.c<br>
> > index e30f8544fc..4361e35e39 100644<br>
> > --- a/lib/net/net_crc_sse.c<br>
> > +++ b/lib/net/net_crc_sse.c<br>
> > @@ -12,15 +12,13 @@<br>
> > #include "net_crc.h"<br>
> ><br>
> > /** PCLMULQDQ CRC computation context structure */<br>
> > -struct crc_pclmulqdq_ctx {<br>
> > - __m128i rk1_rk2;<br>
> > - __m128i rk3_rk4;<br>
> > - __m128i rk5_rk6;<br>
> > - __m128i rk7_rk8;<br>
> > +struct __rte_aligned(XMM_SIZE) crc_pclmulqdq_ctx {<br>
> > + uint64_t rk1_rk2[2];<br>
> > + uint64_t rk3_rk4[2];<br>
> > + uint64_t rk5_rk6[2];<br>
> > + uint64_t rk7_rk8[2];<br>
> > };<br>
> ><br>
> > -static alignas(16) struct crc_pclmulqdq_ctx crc32_eth_pclmulqdq;<br>
> > -static alignas(16) struct crc_pclmulqdq_ctx crc16_ccitt_pclmulqdq;<br>
> > /**<br>
> > * @brief Performs one folding round<br>
> > *<br>
> > @@ -162,7 +160,7 @@ crc32_eth_calc_pclmulqdq(<br>
> > fold3 = _mm_loadu_si128((const __m128i *)(data + 32));<br>
> > fold4 = _mm_loadu_si128((const __m128i *)(data + 48));<br>
> > fold1 = _mm_xor_si128(fold1, temp);<br>
> > - k = params->rk1_rk2;<br>
> > + k = _mm_load_si128((const __m128i *)params->rk1_rk2);<br>
> ><br>
> > for (n = 64; (n + 64) <= data_len; n += 64) {<br>
> > temp1 = _mm_loadu_si128((const __m128i<br>
> *)&data[n]);<br>
> > @@ -175,7 +173,7 @@ crc32_eth_calc_pclmulqdq(<br>
> > fold4 = crcr32_folding_round(temp4, k, fold4);<br>
> > }<br>
> ><br>
> > - k = params->rk3_rk4;<br>
> > + k = _mm_load_si128((const __m128i *)params->rk3_rk4);<br>
> > fold1 = crcr32_folding_round(fold2, k, fold1);<br>
> > fold1 = crcr32_folding_round(fold3, k, fold1);<br>
> > fold = crcr32_folding_round(fold4, k, fold1);<br>
> > @@ -205,7 +203,7 @@ crc32_eth_calc_pclmulqdq(<br>
> > fold = _mm_xor_si128(fold, temp);<br>
> ><br>
> > /** Single folding loop - the last 16 bytes is processed<br>
> separately */<br>
> > - k = params->rk3_rk4;<br>
> > + k = _mm_load_si128((const __m128i *)params->rk3_rk4);<br>
> > n = 16;<br>
> ><br>
> > single_fold_loop:<br>
> > @@ -235,11 +233,11 @@ crc32_eth_calc_pclmulqdq(<br>
> ><br>
> > /** Reduction 128 -> 32 Assumes: fold holds 128bit folded<br>
> data */<br>
> > reduction_128_64:<br>
> > - k = params->rk5_rk6;<br>
> > + k = _mm_load_si128((const __m128i *)params->rk5_rk6);<br>
> > fold = crcr32_reduce_128_to_64(fold, k);<br>
> ><br>
> > barret_reduction:<br>
> > - k = params->rk7_rk8;<br>
> > + k = _mm_load_si128((const __m128i *)params->rk7_rk8);<br>
> > n = crcr32_reduce_64_to_32(fold, k);<br>
> ><br>
> > return n;<br>
> > @@ -248,45 +246,17 @@ crc32_eth_calc_pclmulqdq(<br>
> > void<br>
> > rte_net_crc_sse42_init(void)<br>
> > {<br>
> > - uint64_t k1, k2, k3, k4, k5, k6;<br>
> > - uint64_t p = 0, q = 0;<br>
> > -<br>
> > - /** Initialize CRC16 data */<br>
> > - k1 = 0x14ff2LLU;<br>
> > - k2 = 0x19a3cLLU;<br>
> > - k3 = 0x189aeLLU;<br>
> > - k4 = 0x8e10LLU;<br>
> > - k5 = 0x189aeLLU;<br>
> > - k6 = 0x114aaLLU;<br>
> > - q = 0x11c581910LLU;<br>
> > - p = 0x10811LLU;<br>
> > -<br>
> > - /** Save the params in context structure */<br>
> > - crc16_ccitt_pclmulqdq.rk1_rk2 = _mm_set_epi64x(k2, k1);<br>
> > - crc16_ccitt_pclmulqdq.rk3_rk4 = _mm_set_epi64x(k4, k3);<br>
> > - crc16_ccitt_pclmulqdq.rk5_rk6 = _mm_set_epi64x(k6, k5);<br>
> > - crc16_ccitt_pclmulqdq.rk7_rk8 = _mm_set_epi64x(p, q);<br>
> > -<br>
> > - /** Initialize CRC32 data */<br>
> > - k1 = 0x1c6e41596LLU;<br>
> > - k2 = 0x154442bd4LLU;<br>
> > - k3 = 0xccaa009eLLU;<br>
> > - k4 = 0x1751997d0LLU;<br>
> > - k5 = 0xccaa009eLLU;<br>
> > - k6 = 0x163cd6124LLU;<br>
> > - q = 0x1f7011640LLU;<br>
> > - p = 0x1db710641LLU;<br>
> > -<br>
> > - /** Save the params in context structure */<br>
> > - crc32_eth_pclmulqdq.rk1_rk2 = _mm_set_epi64x(k2, k1);<br>
> > - crc32_eth_pclmulqdq.rk3_rk4 = _mm_set_epi64x(k4, k3);<br>
> > - crc32_eth_pclmulqdq.rk5_rk6 = _mm_set_epi64x(k6, k5);<br>
> > - crc32_eth_pclmulqdq.rk7_rk8 = _mm_set_epi64x(p, q);<br>
> > }<br>
> ><br>
> > uint32_t<br>
> > rte_crc16_ccitt_sse42_handler(const uint8_t *data, uint32_t<br>
> data_len)<br>
> > {<br>
> > + static const struct crc_pclmulqdq_ctx<br>
> crc16_ccitt_pclmulqdq = {<br>
> > + .rk1_rk2 = { 0x14ff2LLU, 0x19a3cLLU },<br>
> > + .rk3_rk4 = { 0x189aeLLU, 0x8e10LLU },<br>
> > + .rk5_rk6 = { 0x189aeLLU, 0x114aaLLU },<br>
> > + .rk7_rk8 = { 0x11c581910LLU, 0x10811LLU },<br>
> > + };<br>
> > /** return 16-bit CRC value */<br>
> > return (uint16_t)~crc32_eth_calc_pclmulqdq(data,<br>
> > data_len,<br>
> > @@ -297,6 +267,12 @@ rte_crc16_ccitt_sse42_handler(const uint8_t<br>
> *data, uint32_t data_len)<br>
> > uint32_t<br>
> > rte_crc32_eth_sse42_handler(const uint8_t *data, uint32_t<br>
> data_len)<br>
> > {<br>
> > + static const struct crc_pclmulqdq_ctx crc32_eth_pclmulqdq = {<br>
> > + .rk1_rk2 = { 0x1c6e41596LLU, 0x154442bd4LLU },<br>
> > + .rk3_rk4 = { 0xccaa009eLLU, 0x1751997d0LLU },<br>
> > + .rk5_rk6 = { 0xccaa009eLLU, 0x163cd6124LLU },<br>
> > + .rk7_rk8 = { 0x1f7011640LLU, 0x1db710641LLU },<br>
> > + };<br>
> > return ~crc32_eth_calc_pclmulqdq(data,<br>
> > data_len,<br>
> > 0xffffffffUL,<br>
><br>
<br>
</blockquote></div></div>