git: cae3be82c3cd - stable/13 - mlx5ib: Simplify mlx5_ib_cont_pages()

Hans Petter Selasky hselasky at FreeBSD.org
Mon Jul 26 16:13:10 UTC 2021


The branch stable/13 has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=cae3be82c3cd16e73b94a7320314b7d402275e35

commit cae3be82c3cd16e73b94a7320314b7d402275e35
Author:     Hans Petter Selasky <hselasky at FreeBSD.org>
AuthorDate: 2021-06-16 13:01:30 +0000
Commit:     Hans Petter Selasky <hselasky at FreeBSD.org>
CommitDate: 2021-07-26 16:04:28 +0000

    mlx5ib: Simplify mlx5_ib_cont_pages()
    
    The patch simplifies mlx5_ib_cont_pages and fixes the following
    issues in the original implementation:
    
    First issues is related to alignment of the PFNs. After the check
    base + p != PFN, the alignment of the PFN wasn't checked. So the PFN
    sequence 0, 1, 1, 2 would result in a page_shift of 13 even though
    the 3rd PFN is not 8KB aligned.
    
    This wasn't actually a bug because it was supported by all the
    existing mlx5 compatible device, but we don't want to require
    this support in all future devices.
    
    Another issue is because the inner loop didn't advance PFN so
    the test "if (base + p != pfn)" always failed for SGE with
    len > (1<<page_shift).
    
    Linux commit:
    d67bc5d4e3e100d762c0f57ea67f28bc219698a6
    
    Reviewed by:    kib
    Sponsored by:   Mellanox Technologies // NVIDIA Networking
    
    (cherry picked from commit 21bc3710a4b46655067cbad54d1f21952c871dd2)
---
 sys/dev/mlx5/mlx5_ib/mlx5_ib_mem.c | 69 ++++++++++++--------------------------
 1 file changed, 22 insertions(+), 47 deletions(-)

diff --git a/sys/dev/mlx5/mlx5_ib/mlx5_ib_mem.c b/sys/dev/mlx5/mlx5_ib/mlx5_ib_mem.c
index 58f985b33ff4..97d9d33603d6 100644
--- a/sys/dev/mlx5/mlx5_ib/mlx5_ib_mem.c
+++ b/sys/dev/mlx5/mlx5_ib/mlx5_ib_mem.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2013-2015, Mellanox Technologies, Ltd.  All rights reserved.
+ * Copyright (c) 2013-2020, Mellanox Technologies, Ltd.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,58 +42,33 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
 {
 	unsigned long tmp;
 	unsigned long m;
-	int i, k;
-	u64 base = 0;
-	int p = 0;
-	int skip;
-	int mask;
-	u64 len;
-	u64 pfn;
+	u64 base = ~0, p = 0;
+	u64 len, pfn;
+	int i = 0;
 	struct scatterlist *sg;
 	int entry;
-	unsigned long page_shift = ilog2(umem->page_size);
-
-	/* With ODP we must always match OS page size. */
-	if (umem->odp_data) {
-		*count = ib_umem_page_count(umem);
-		*shift = PAGE_SHIFT;
-		*ncont = *count;
-		if (order)
-			*order = ilog2(roundup_pow_of_two(*count));
-
-		return;
-	}
 
-	addr = addr >> page_shift;
+	addr = addr >> PAGE_SHIFT;
 	tmp = (unsigned long)addr;
 	m = find_first_bit(&tmp, BITS_PER_LONG);
-	skip = 1 << m;
-	mask = skip - 1;
-	i = 0;
+
 	for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) {
-		len = sg_dma_len(sg) >> page_shift;
-		pfn = sg_dma_address(sg) >> page_shift;
-		for (k = 0; k < len; k++) {
-			if (!(i & mask)) {
-				tmp = (unsigned long)pfn;
-				m = min_t(unsigned long, m, find_first_bit(&tmp, BITS_PER_LONG));
-				skip = 1 << m;
-				mask = skip - 1;
-				base = pfn;
-				p = 0;
-			} else {
-				if (base + p != pfn) {
-					tmp = (unsigned long)p;
-					m = find_first_bit(&tmp, BITS_PER_LONG);
-					skip = 1 << m;
-					mask = skip - 1;
-					base = pfn;
-					p = 0;
-				}
-			}
-			p++;
-			i++;
+		len = sg_dma_len(sg) >> PAGE_SHIFT;
+		pfn = sg_dma_address(sg) >> PAGE_SHIFT;
+		if (base + p != pfn) {
+			/* If either the offset or the new
+			 * base are unaligned update m
+			 */
+			tmp = (unsigned long)(pfn | p);
+			if (!IS_ALIGNED(tmp, 1 << m))
+				m = find_first_bit(&tmp, BITS_PER_LONG);
+
+			base = pfn;
+			p = 0;
 		}
+
+		p += len;
+		i += len;
 	}
 
 	if (i) {
@@ -111,7 +86,7 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, int *count, int *shift,
 
 		*ncont = 0;
 	}
-	*shift = page_shift + m;
+	*shift = PAGE_SHIFT + m;
 	*count = i;
 }
 


More information about the dev-commits-src-all mailing list