xsk: Elide base_addr comparison in xp_unaligned_validate_desc
authorKal Conley <kal.conley@dectris.com>
Tue, 11 Apr 2023 13:00:25 +0000 (15:00 +0200)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 13 Apr 2023 13:00:11 +0000 (15:00 +0200)
Remove redundant (base_addr >= pool->addrs_cnt) comparison from the
conditional.

In particular, addr is computed as:

    addr = base_addr + offset

... where base_addr and offset are stored as 48-bit and 16-bit unsigned
integers, respectively. The above sum cannot overflow u64 since base_addr
has a maximum value of 0x0000ffffffffffff and offset has a maximum value
of 0xffff (implying a maximum sum of 0x000100000000fffe). Since overflow
is impossible, it follows that addr >= base_addr.

Now if (base_addr >= pool->addrs_cnt), then clearly:

    addr >= base_addr
         >= pool->addrs_cnt

Thus, (base_addr >= pool->addrs_cnt) implies (addr >= pool->addrs_cnt).
Subsequently, the former comparison is unnecessary in the conditional
since for any boolean expressions A and B, (A || B) && (A -> B) is
equivalent to B.

Signed-off-by: Kal Conley <kal.conley@dectris.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Magnus Karlsson <magnus.karlsson@intel.com>
Link: https://lore.kernel.org/bpf/20230411130025.19704-1-kal.conley@dectris.com
net/xdp/xsk_queue.h

index 76b574b..6d40a77 100644 (file)
@@ -149,16 +149,12 @@ static inline bool xp_aligned_validate_desc(struct xsk_buff_pool *pool,
 static inline bool xp_unaligned_validate_desc(struct xsk_buff_pool *pool,
                                              struct xdp_desc *desc)
 {
-       u64 addr, base_addr;
-
-       base_addr = xp_unaligned_extract_addr(desc->addr);
-       addr = xp_unaligned_add_offset_to_addr(desc->addr);
+       u64 addr = xp_unaligned_add_offset_to_addr(desc->addr);
 
        if (desc->len > pool->chunk_size)
                return false;
 
-       if (base_addr >= pool->addrs_cnt || addr >= pool->addrs_cnt ||
-           addr + desc->len > pool->addrs_cnt ||
+       if (addr >= pool->addrs_cnt || addr + desc->len > pool->addrs_cnt ||
            xp_desc_crosses_non_contig_pg(pool, addr, desc->len))
                return false;