svn commit: r335413 - stable/11/sys/compat/linuxkpi/common/include/linux
Hans Petter Selasky
hselasky at FreeBSD.org
Wed Jun 20 06:37:16 UTC 2018
Author: hselasky
Date: Wed Jun 20 06:37:15 2018
New Revision: 335413
URL: https://svnweb.freebsd.org/changeset/base/335413
Log:
MFC r334484:
Implement the __sg_alloc_table_from_pages() function based on the existing
sg_alloc_table_from_pages() function in the LinuxKPI.
This basically allow segments to have a limit, max_segment.
Submitted by: Johannes Lundberg <johalun0 at gmail.com>
Sponsored by: Mellanox Technologies
Sponsored by: Limelight Networks
Modified:
stable/11/sys/compat/linuxkpi/common/include/linux/scatterlist.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/compat/linuxkpi/common/include/linux/scatterlist.h
==============================================================================
--- stable/11/sys/compat/linuxkpi/common/include/linux/scatterlist.h Wed Jun 20 06:36:25 2018 (r335412)
+++ stable/11/sys/compat/linuxkpi/common/include/linux/scatterlist.h Wed Jun 20 06:37:15 2018 (r335413)
@@ -64,6 +64,8 @@ struct sg_page_iter {
} internal;
};
+#define SCATTERLIST_MAX_SEGMENT (-1U & ~(PAGE_SIZE - 1))
+
#define SG_MAX_SINGLE_ALLOC (PAGE_SIZE / sizeof(struct scatterlist))
#define SG_MAGIC 0x87654321UL
@@ -286,18 +288,26 @@ sg_alloc_table(struct sg_table *table, unsigned int ne
}
static inline int
-sg_alloc_table_from_pages(struct sg_table *sgt,
+__sg_alloc_table_from_pages(struct sg_table *sgt,
struct page **pages, unsigned int count,
unsigned long off, unsigned long size,
- gfp_t gfp_mask)
+ unsigned int max_segment, gfp_t gfp_mask)
{
- unsigned int i, segs, cur;
+ unsigned int i, segs, cur, len;
int rc;
struct scatterlist *s;
+ if (__predict_false(!max_segment || offset_in_page(max_segment)))
+ return (-EINVAL);
+
+ len = 0;
for (segs = i = 1; i < count; ++i) {
- if (page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1)
+ len += PAGE_SIZE;
+ if (len >= max_segment ||
+ page_to_pfn(pages[i]) != page_to_pfn(pages[i - 1]) + 1) {
++segs;
+ len = 0;
+ }
}
if (__predict_false((rc = sg_alloc_table(sgt, segs, gfp_mask))))
return (rc);
@@ -307,10 +317,13 @@ sg_alloc_table_from_pages(struct sg_table *sgt,
unsigned long seg_size;
unsigned int j;
- for (j = cur + 1; j < count; ++j)
- if (page_to_pfn(pages[j]) !=
+ len = 0;
+ for (j = cur + 1; j < count; ++j) {
+ len += PAGE_SIZE;
+ if (len >= max_segment || page_to_pfn(pages[j]) !=
page_to_pfn(pages[j - 1]) + 1)
break;
+ }
seg_size = ((j - cur) << PAGE_SHIFT) - off;
sg_set_page(s, pages[cur], min(size, seg_size), off);
@@ -321,6 +334,16 @@ sg_alloc_table_from_pages(struct sg_table *sgt,
return (0);
}
+static inline int
+sg_alloc_table_from_pages(struct sg_table *sgt,
+ struct page **pages, unsigned int count,
+ unsigned long off, unsigned long size,
+ gfp_t gfp_mask)
+{
+
+ return (__sg_alloc_table_from_pages(sgt, pages, count, off, size,
+ SCATTERLIST_MAX_SEGMENT, gfp_mask));
+}
static inline int
sg_nents(struct scatterlist *sg)
More information about the svn-src-stable
mailing list