Re: [PATCH net-next v2 6/6] net: qualcomm: rmnet: don't use C bit-fields in rmnet checksum header
From: Alex Elder <hidden>
Date: 2021-03-08 14:00:28
Also in:
lkml
On 3/8/21 4:18 AM, David Laight wrote:
From: Alex Elderquoted
Sent: 06 March 2021 03:16 Replace the use of C bit-fields in the rmnet_map_ul_csum_header structure with a single two-byte (big endian) structure member, and use field masks to encode or get values within it. Previously rmnet_map_ipv4_ul_csum_header() would update values in the host byte-order fields, and then forcibly fix their byte order using a combination of byte order operations and types. Instead, just compute the value that needs to go into the new structure member and save it with a simple byte-order conversion. Make similar simplifications in rmnet_map_ipv6_ul_csum_header(). Finally, in rmnet_map_checksum_uplink_packet() a set of assignments zeroes every field in the upload checksum header. Replace that with a single memset() operation. Signed-off-by: Alex Elder <redacted> Reported-by: kernel test robot <redacted> --- v2: Fixed to use u16_encode_bits() instead of be16_encode_bits(). .../ethernet/qualcomm/rmnet/rmnet_map_data.c | 34 ++++++------------- include/linux/if_rmnet.h | 21 ++++++------ 2 files changed, 21 insertions(+), 34 deletions(-)diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.cb/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c index 29d485b868a65..b76ad48da7325 100644--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c@@ -198,23 +198,19 @@ rmnet_map_ipv4_ul_csum_header(void *iphdr, struct rmnet_map_ul_csum_header *ul_header, struct sk_buff *skb) { - __be16 *hdr = (__be16 *)ul_header; struct iphdr *ip4h = iphdr; u16 offset; + u16 val; offset = skb_transport_header(skb) - (unsigned char *)iphdr; ul_header->csum_start_offset = htons(offset); - ul_header->csum_insert_offset = skb->csum_offset; - ul_header->csum_enabled = 1; + val = u16_encode_bits(1, MAP_CSUM_UL_ENABLED_FMASK); if (ip4h->protocol == IPPROTO_UDP) - ul_header->udp_ind = 1; - else - ul_header->udp_ind = 0; + val |= u16_encode_bits(1, MAP_CSUM_UL_UDP_FMASK); + val |= u16_encode_bits(skb->csum_offset, MAP_CSUM_UL_OFFSET_FMASK); - /* Changing remaining fields to network order */ - hdr++; - *hdr = htons((__force u16)*hdr); + ul_header->csum_info = htons(val);Isn't this potentially misaligned?
At first I thought you were talking about column alignment. The short answer: Yes (at least it's possible)! And that's a problem elsewhere in the driver. I noticed that before and confirmed that unaligned accesses *do* occur in this driver. I would want to fix that comprehensively (and separate from this patch), and not just in this one spot. I have not done it because I am not set up to readily test the change; unaligned access does not cause a fault on aarch64 (or at least on the platforms I'm using). Sort of related, I have been meaning to eliminate the pointless __aligned(1) tags on rmnet structures defined in <linux/if_rmnet.h>. It wouldn't hurt to use __packed, though I think they're all 4 or 8 bytes naturally anyway. Perhaps marking them __aligned(4) would help identify potential unaligned accesses? Anyway, assuming you're not talking about tab stops, yes it's possible this assignment is misaligned. But it's a bigger problem than what you point out. I will take this as a sign that I'm not the only one who has this concern, meaning I should maybe bump the priority on getting this alignment thing fixed. -Alex
David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)