On 22 August 2017 at 13:31, Paul Blakey <pa...@mellanox.com> wrote: > > > On 22/08/2017 23:07, Paul Blakey wrote: >> >> >> >> On 21/08/2017 20:45, Joe Stringer wrote: >>> >>> On 20 August 2017 at 01:50, Paul Blakey <pa...@mellanox.com> wrote: >>>> >>>> >>>> >>>> On 18/08/2017 00:52, Joe Stringer wrote: >>>>> >>>>> >>>>> On 17 August 2017 at 02:18, Paul Blakey <pa...@mellanox.com> wrote: >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On 15/08/2017 20:04, Joe Stringer wrote: >>>>>>> >>>>>>> >>>>>>> >>>>>>> On 15 August 2017 at 01:19, Paul Blakey <pa...@mellanox.com> wrote: >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> On 15/08/2017 00:56, Joe Stringer wrote: >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> On 8 August 2017 at 07:21, Roi Dayan <r...@mellanox.com> wrote: >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> From: Paul Blakey <pa...@mellanox.com> >>>>>>>>>> >>>>>>>>>> @@ -117,6 +118,17 @@ struct tc_flower { >>>>>>>>>> uint64_t lastused; >>>>>>>>>> >>>>>>>>>> struct { >>>>>>>>>> + bool rewrite; >>>>>>>>>> + uint8_t pad1[3]; >>>>>>>>>> + struct tc_flower_key key; >>>>>>>>>> + uint8_t pad2[3]; >>>>>>>>>> + struct tc_flower_key mask; >>>>>>>>>> + uint8_t pad3[3]; >>>>>>>>>> + } rewrite; >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> Now that I get why the pads are here.. ;) >>>>>>> >>>>>>> Is there an existing macro we can use to ensure that these pad out to >>>>>>> 32-bit boundaries? >>>>>>> >>>>>> >>>>>> I'm not sure if that's possible, the size is a minimum of extra >>>>>> 24bits, >>>>>> so >>>>>> its can't overflow with writing on any address below it. The compiler >>>>>> might add some extra padding but that shouldn't matter. >>>>> >>>>> >>>>> >>>>> My thought was that the main concern here is to align the fields to >>>>> 32-bit boundaries, so if it already does this then I wouldn't expect >>>>> to need any padding at all? For instance, on my system with these >>>>> patches I see with pahole that 'struct tc_flower_key' has size 84, and >>>>> the 'pad2' and 'pad3' appear to be unnecessary: >>>>> >>>>> struct { >>>>> _Bool rewrite; /* 216 >>>>> 1 */ >>>>> uint8_t pad1[0]; /* 217 >>>>> 0 */ >>>>> struct tc_flower_key key; /* 220 >>>>> 84 */ >>>>> /* --- cacheline 1 boundary (64 bytes) was 21 bytes >>>>> ago >>>>> --- */ >>>>> uint8_t pad2[0]; /* 304 >>>>> 0 */ >>>>> struct tc_flower_key mask; /* 308 >>>>> 84 */ >>>>> /* --- cacheline 2 boundary (128 bytes) was 41 bytes >>>>> ago >>>>> --- */ >>>>> uint8_t pad3[0]; /* 392 >>>>> 0 */ >>>>> } rewrite; /* 216 >>>>> 180 */ >>>>> >>>>> However, if in future someone adds a 1-byte member to tc_flower_key >>>>> then I'm not sure that this alignment will hold. On my system, it >>>>> seems like that would end up padding tc_flower_key out to 88B so these >>>>> extra padding would still be unnecessary (although pahole says that it >>>>> has a brain fart, so I'm not sure exactly how much confidence I should >>>>> have in this). >>>>> >>>>> What I was thinking about was whether we could use something like >>>>> PADDED_MEMBERS() in this case. >>>>> >>>> >>>> Are you talking about alignment in regards to performance? >>>> Because the padding is there for overflowing. >>>> If someone adds a new member to struct key/mask that is smaller than a >>>> 32bits to the end of the struct, setting it via a pointer might overflow >>>> the >>>> struct. I don't think PADDED_MEMBERS will work for this type of padding. >>>> >>>> We do mask the write to the write size, and it should still be in memory >>>> of >>>> owned by struct flower and since the compiler can't reorder the struct >>>> we >>>> actually only need the last padding to cover the above case. >>>> >>>> Maybe we can add alignment when we measure the performance of the code? >>> >>> >>> Ah. I wasn't concerned about performance, I was just wondering if this >>> forces us to add a few extra unnecessary bytes to 'rewrite' regardless >>> of the size of 'struct tc_flower'. For instance, if 'struct tc_flower' >>> is 63B long because someone adds a small field to the end of the >>> structure, then I'd expect to need only one extra byte of padding. If >>> it were a multiple of 32 bits, I wouldn't expect any need for padding >>> at all. >>> >> >> I see. You're right but keep in mind that this struct is on the stack and >> a couple of bytes shouldn't matter much. I'm not sure how to define a macro >> that adds padding based on the last member in the struct unless I do define >> it like PADDED_MEMBERS but with the last member isolated from >> the rest (e.g PAD_TO_LAST(unit, members, last_member)) so I can test it's >> size. A build time assert would be the same. >> >> Since we mask the writes/reads, Maybe we can assert whether reading 32bit >> (or actually 24bit) past the struct rewrite is within struct flower bounds. >> Basically that no one moved it to the end of struct flower. >> >> pseudo code: BUILD_DECL_ASSERT(member_offsetof(flower.rewrite) + >> sizeof(uint32_t) < sizeof(struct flower)) > > > BUILD_DECL_ASSERT(member_offsetof(flower.rewrite) + sizeof(flower.rewrite) + > sizeof(uint32_t) -1 < sizeof(struct flower))
Could we just check that (member_offsetof(flower.rewrite) + sizeof(flower.rewrite)) % sizeof(uint32_t) == 0 ? Also for the flower.rewrite.key and flower.rewrite.mask ? _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev