Page MenuHomeFreeBSD

D53440.id.diff
No OneTemporary

D53440.id.diff

diff --git a/sys/compat/linuxkpi/common/include/asm/set_memory.h b/sys/compat/linuxkpi/common/include/asm/set_memory.h
--- a/sys/compat/linuxkpi/common/include/asm/set_memory.h
+++ b/sys/compat/linuxkpi/common/include/asm/set_memory.h
@@ -67,17 +67,30 @@
{
KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages));
+#ifdef PAGE_IS_LKPI_PAGE
+ pmap_page_set_memattr(page->vm_page, VM_MEMATTR_UNCACHEABLE);
+#else
pmap_page_set_memattr(page, VM_MEMATTR_UNCACHEABLE);
+#endif
return (0);
}
static inline int
set_pages_wc(struct page *page, int numpages)
{
+#ifdef VM_MEMATTR_WRITE_COMBINING
+ vm_page_t vmp;
+#endif
+
KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages));
#ifdef VM_MEMATTR_WRITE_COMBINING
- pmap_page_set_memattr(page, VM_MEMATTR_WRITE_COMBINING);
+#ifdef PAGE_IS_LKPI_PAGE
+ vmp = page->vm_page;
+#else
+ vmp = page;
+#endif
+ pmap_page_set_memattr(vmp, VM_MEMATTR_WRITE_COMBINING);
#else
return (set_pages_uc(page, numpages));
#endif
@@ -89,7 +102,11 @@
{
KASSERT(numpages == 1, ("%s: numpages %d", __func__, numpages));
+#ifdef PAGE_IS_LKPI_PAGE
+ pmap_page_set_memattr(page->vm_page, VM_MEMATTR_WRITE_BACK);
+#else
pmap_page_set_memattr(page, VM_MEMATTR_WRITE_BACK);
+#endif
return (0);
}
diff --git a/sys/compat/linuxkpi/common/include/linux/highmem.h b/sys/compat/linuxkpi/common/include/linux/highmem.h
--- a/sys/compat/linuxkpi/common/include/linux/highmem.h
+++ b/sys/compat/linuxkpi/common/include/linux/highmem.h
@@ -64,7 +64,11 @@
return ((void *)PHYS_TO_DMAP(page_to_phys(page)));
} else {
sched_pin();
+#ifdef PAGE_IS_LKPI_PAGE
+ sf = sf_buf_alloc(page->vm_page, SFB_NOWAIT | SFB_CPUPRIVATE);
+#else
sf = sf_buf_alloc(page, SFB_NOWAIT | SFB_CPUPRIVATE);
+#endif
if (sf == NULL) {
sched_unpin();
return (NULL);
@@ -79,8 +83,13 @@
vm_memattr_t attr = pgprot2cachemode(prot);
if (attr != VM_MEMATTR_DEFAULT) {
+#ifdef PAGE_IS_LKPI_PAGE
+ page->vm_page->flags |= PG_FICTITIOUS;
+ pmap_page_set_memattr(page->vm_page, attr);
+#else
page->flags |= PG_FICTITIOUS;
pmap_page_set_memattr(page, attr);
+#endif
}
return (kmap(page));
}
@@ -112,7 +121,11 @@
if (!PMAP_HAS_DMAP) {
/* lookup SF buffer in list */
+#ifdef PAGE_IS_LKPI_PAGE
+ sf = sf_buf_alloc(page->vm_page, SFB_NOWAIT | SFB_CPUPRIVATE);
+#else
sf = sf_buf_alloc(page, SFB_NOWAIT | SFB_CPUPRIVATE);
+#endif
/* double-free */
sf_buf_free(sf);
diff --git a/sys/compat/linuxkpi/common/include/linux/mm.h b/sys/compat/linuxkpi/common/include/linux/mm.h
--- a/sys/compat/linuxkpi/common/include/linux/mm.h
+++ b/sys/compat/linuxkpi/common/include/linux/mm.h
@@ -268,19 +268,31 @@
static inline void
set_page_dirty(struct page *page)
{
+#ifdef PAGE_IS_LKPI_PAGE
+ vm_page_dirty(page->vm_page);
+#else
vm_page_dirty(page);
+#endif
}
static inline void
mark_page_accessed(struct page *page)
{
+#ifdef PAGE_IS_LKPI_PAGE
+ vm_page_reference(page->vm_page);
+#else
vm_page_reference(page);
+#endif
}
static inline void
get_page(struct page *page)
{
+#ifdef PAGE_IS_LKPI_PAGE
+ vm_page_wire(page->vm_page);
+#else
vm_page_wire(page);
+#endif
}
static inline void
@@ -374,7 +386,15 @@
#define unpin_user_page(page) put_page(page)
#define unpin_user_pages(pages, npages) release_pages(pages, npages)
+#ifdef PAGE_IS_LKPI_PAGE
+static inline void
+copy_highpage(struct page *to, struct page *from)
+{
+ pmap_copy_page(from->vm_page, to->vm_page);
+}
+#else
#define copy_highpage(to, from) pmap_copy_page(from, to)
+#endif
static inline pgprot_t
vm_get_page_prot(unsigned long vm_flags)
@@ -400,20 +420,32 @@
vm_paddr_t paddr;
paddr = pmap_kextract((vm_offset_t)addr);
+#ifdef PAGE_IS_LKPI_PAGE
+ panic("XXX-BZ TODO: %jx", (uintmax_t)paddr);
+#else
return (PHYS_TO_VM_PAGE(paddr));
+#endif
}
static inline int
trylock_page(struct page *page)
{
+#ifdef PAGE_IS_LKPI_PAGE
+ return (vm_page_tryxbusy(page->vm_page));
+#else
return (vm_page_tryxbusy(page));
+#endif
}
static inline void
unlock_page(struct page *page)
{
+#ifdef PAGE_IS_LKPI_PAGE
+ vm_page_xunbusy(page->vm_page);
+#else
vm_page_xunbusy(page);
+#endif
}
extern int is_vmalloc_addr(const void *addr);
diff --git a/sys/compat/linuxkpi/common/include/linux/page.h b/sys/compat/linuxkpi/common/include/linux/page.h
--- a/sys/compat/linuxkpi/common/include/linux/page.h
+++ b/sys/compat/linuxkpi/common/include/linux/page.h
@@ -48,7 +48,24 @@
typedef unsigned long linux_pgd_t;
typedef unsigned long pgprot_t;
+#ifdef __not_yet__
+#define PAGE_IS_LKPI_PAGE
+#endif
+#ifdef PAGE_IS_LKPI_PAGE
+struct page {
+ /* Native FreeBSD vm_page. */
+ struct vm_page *vm_page;
+
+ /* Linux fields. */
+ struct page_pool *pp;
+ dma_addr_t dma_addr;
+
+ uintptr_t private; /* drm-kmod ttm-pool */
+ struct list_head lru;
+};
+#else
#define page vm_page
+#endif
#define LINUXKPI_PROT_VALID (1 << 3)
#define LINUXKPI_CACHE_MODE_SHIFT 4
@@ -72,14 +89,30 @@
return (VM_MEMATTR_DEFAULT);
}
-#define page_to_virt(page) linux_page_address(page)
+#ifdef PAGE_IS_LKPI_PAGE
+struct page *lkpi_vm_page_to_page(struct vm_page *); /* Internal */
+struct page *linuxkpi_virt_to_page(const void *);
+struct page *linuxkpi_pfn_to_page(unsigned long);
+
+#define virt_to_page(_v) linuxkpi_virt_to_page(_v)
+#define page_to_pfn(_page) (VM_PAGE_TO_PHYS((_page)->vm_page) >> PAGE_SHIFT)
+#define pfn_to_page(_pfn) linuxkpi_pfn_to_page(_pfn)
+#define page_to_phys(_page) VM_PAGE_TO_PHYS((_page)->vm_page)
+#else
#define virt_to_page(x) PHYS_TO_VM_PAGE(vtophys(x))
#define page_to_pfn(pp) (VM_PAGE_TO_PHYS(pp) >> PAGE_SHIFT)
#define pfn_to_page(pfn) (PHYS_TO_VM_PAGE((pfn) << PAGE_SHIFT))
-#define nth_page(page,n) pfn_to_page(page_to_pfn(page) + (n))
#define page_to_phys(page) VM_PAGE_TO_PHYS(page)
+#endif
+#define page_to_virt(page) linux_page_address(page)
+#define nth_page(page,n) pfn_to_page(page_to_pfn(page) + (n))
+
+/*
+ * clear_page() is also called on kmem allocated pages.
+ * [2023-07-31] mthca(4) is the only in-tree consumer.
+ */
+#define clear_page(page) memset(page, 0, PAGE_SIZE)
-#define clear_page(page) memset(page, 0, PAGE_SIZE)
#define pgprot_noncached(prot) \
(((prot) & VM_PROT_ALL) | cachemode2protval(VM_MEMATTR_UNCACHEABLE))
#ifdef VM_MEMATTR_WRITE_COMBINING
diff --git a/sys/compat/linuxkpi/common/include/linux/scatterlist.h b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
--- a/sys/compat/linuxkpi/common/include/linux/scatterlist.h
+++ b/sys/compat/linuxkpi/common/include/linux/scatterlist.h
@@ -596,7 +596,11 @@
len = min(piter.sg->length - skip, buflen);
page = sg_page_iter_page(&piter);
+#ifdef PAGE_IS_LKPI_PAGE
+ sf = sf_buf_alloc(page->vm_page, SFB_CPUPRIVATE | SFB_NOWAIT);
+#else
sf = sf_buf_alloc(page, SFB_CPUPRIVATE | SFB_NOWAIT);
+#endif
if (sf == NULL)
break;
p = (char *)sf_buf_kva(sf) + piter.sg_pgoffset + skip;
@@ -651,7 +655,11 @@
page = sg_page_iter_page(&iter);
if (!PMAP_HAS_DMAP) {
+#ifdef PAGE_IS_LKPI_PAGE
+ sf = sf_buf_alloc(page->vm_page, SFB_CPUPRIVATE | SFB_NOWAIT);
+#else
sf = sf_buf_alloc(page, SFB_CPUPRIVATE | SFB_NOWAIT);
+#endif
if (sf == NULL)
break;
vaddr = (char *)sf_buf_kva(sf);
diff --git a/sys/compat/linuxkpi/common/src/linux_page.c b/sys/compat/linuxkpi/common/src/linux_page.c
--- a/sys/compat/linuxkpi/common/src/linux_page.c
+++ b/sys/compat/linuxkpi/common/src/linux_page.c
@@ -82,17 +82,46 @@
si->mem_unit = PAGE_SIZE;
}
+#ifdef PAGE_IS_LKPI_PAGE
+static void
+lkpi_page_set_vm_page(struct page *page, struct vm_page *m)
+{
+
+ KASSERT(page->vm_page == NULL,
+ ("%s: page %p page->vm_page %p != NULL; vm_page %p\n", __func__,
+ page, page->vm_page, m));
+
+ page->vm_page = m;
+}
+
+static void
+lkpi_page_unset_vm_page(struct page *page)
+{
+ KASSERT(page->vm_page != NULL, ("%s: page %p page->vm_page %p is NULL\n",
+ __func__, page, page->vm_page));
+
+ page->vm_page = NULL;
+}
+#endif
+
void *
linux_page_address(const struct page *page)
{
+ const struct vm_page *m;
- if (page->object != kernel_object) {
+#ifdef PAGE_IS_LKPI_PAGE
+ m = page->vm_page;
+#else
+ m = page;
+#endif
+
+ if (m->object != kernel_object) {
return (PMAP_HAS_DMAP ?
((void *)(uintptr_t)PHYS_TO_DMAP(page_to_phys(page))) :
NULL);
}
return ((void *)(uintptr_t)(VM_MIN_KERNEL_ADDRESS +
- IDX_TO_OFF(page->pindex)));
+ IDX_TO_OFF(m->pindex)));
}
struct page *
@@ -101,15 +130,19 @@
struct page *page;
if (PMAP_HAS_DMAP) {
+ struct vm_page *m;
unsigned long npages = 1UL << order;
+#ifdef PAGE_IS_LKPI_PAGE
+ unsigned long x;
+#endif
int req = VM_ALLOC_WIRED;
if ((flags & M_ZERO) != 0)
req |= VM_ALLOC_ZERO;
if (order == 0 && (flags & GFP_DMA32) == 0) {
- page = vm_page_alloc_noobj(req);
- if (page == NULL)
+ m = vm_page_alloc_noobj(req);
+ if (m == NULL)
return (NULL);
} else {
vm_paddr_t pmax = (flags & GFP_DMA32) ?
@@ -119,11 +152,10 @@
req |= VM_ALLOC_NORECLAIM;
retry:
- page = vm_page_alloc_noobj_contig(req, npages, 0, pmax,
+ m = vm_page_alloc_noobj_contig(req, npages, 0, pmax,
PAGE_SIZE, 0, VM_MEMATTR_DEFAULT);
- if (page == NULL) {
- if ((flags & (M_WAITOK | __GFP_NORETRY)) ==
- M_WAITOK) {
+ if (m == NULL) {
+ if (flags & M_WAITOK) {
int err = vm_page_reclaim_contig(req,
npages, 0, pmax, PAGE_SIZE, 0);
if (err == ENOMEM)
@@ -136,7 +168,19 @@
return (NULL);
}
}
+#ifdef PAGE_IS_LKPI_PAGE
+ page = lkpi_vm_page_to_page(m);
+ for (x = 0; x < npages; x++)
+ lkpi_page_set_vm_page(page + x, m + x);
+#else
+ page = m;
+#endif
} else {
+#ifdef PAGE_IS_LKPI_PAGE
+ unsigned long npages = 1UL << order;
+ unsigned long x;
+ struct vm_page *m;
+#endif
vm_offset_t vaddr;
vaddr = linux_alloc_kmem(flags, order);
@@ -144,6 +188,11 @@
return (NULL);
page = virt_to_page((void *)vaddr);
+#ifdef PAGE_IS_LKPI_PAGE
+ m = PHYS_TO_VM_PAGE(vtophys(vaddr));
+ for (x = 0; x < npages; x++)
+ lkpi_page_set_vm_page(page + x, m + x);
+#endif
KASSERT(vaddr == (vm_offset_t)page_address(page),
("Page address mismatch"));
@@ -156,6 +205,15 @@
_linux_free_kmem(vm_offset_t addr, unsigned int order)
{
size_t size = ((size_t)PAGE_SIZE) << order;
+#ifdef PAGE_IS_LKPI_PAGE
+ unsigned long npages = 1UL << order;
+ unsigned long x;
+ struct page *page;
+
+ page = virt_to_page((void *)addr);
+ for (x = 0; x != npages; x++)
+ lkpi_page_unset_vm_page(page + x);
+#endif
kmem_free((void *)addr, size);
}
@@ -164,11 +222,17 @@
linux_free_pages(struct page *page, unsigned int order)
{
if (PMAP_HAS_DMAP) {
+ struct vm_page *m;
unsigned long npages = 1UL << order;
unsigned long x;
+#ifdef PAGE_IS_LKPI_PAGE
+ m = page->vm_page;
+#else
+ m = page;
+#endif
for (x = 0; x != npages; x++) {
- vm_page_t pgo = page + x;
+ vm_page_t pgo = m + x;
/*
* The "free page" function is used in several
@@ -183,17 +247,23 @@
* or not here.
*/
if ((pgo->oflags & VPO_UNMANAGED) == 0) {
+#ifdef PAGE_IS_LKPI_PAGE
+ lkpi_page_unset_vm_page(page + x);
+#endif
vm_page_unwire(pgo, PQ_ACTIVE);
} else {
- if (vm_page_unwire_noq(pgo))
+ if (vm_page_unwire_noq(pgo)) {
+#ifdef PAGE_IS_LKPI_PAGE
+ lkpi_page_unset_vm_page(page + x);
+#endif
vm_page_free(pgo);
+ }
}
}
} else {
vm_offset_t vaddr;
vaddr = (vm_offset_t)page_address(page);
-
_linux_free_kmem(vaddr, order);
}
}
@@ -231,9 +301,15 @@
if (addr >= VM_MIN_KERNEL_ADDRESS && addr < VM_MAX_KERNEL_ADDRESS) {
_linux_free_kmem(addr, order);
} else {
- vm_page_t page;
+ struct page *page;
+ vm_page_t mp;
- page = PHYS_TO_VM_PAGE(DMAP_TO_PHYS(addr));
+ mp = PHYS_TO_VM_PAGE(DMAP_TO_PHYS(addr));
+#ifdef PAGE_IS_LKPI_PAGE
+ page = lkpi_vm_page_to_page(mp);
+#else
+ page = mp;
+#endif
linux_free_pages(page, order);
}
}
@@ -242,13 +318,26 @@
linux_get_user_pages_internal(vm_map_t map, unsigned long start, int nr_pages,
int write, struct page **pages)
{
+ struct vm_page **mpp;
vm_prot_t prot;
size_t len;
- int count;
+ int count, i;
+
+ mpp = malloc(sizeof(*mpp) * nr_pages, M_KMALLOC, M_NOWAIT|M_ZERO);
+ if (mpp == NULL)
+ return (-ENOMEM);
+
+ for (i = 0; i < nr_pages; i++)
+#ifdef PAGE_IS_LKPI_PAGE
+ mpp[i] = pages[i]->vm_page;
+#else
+ mpp[i] = pages[i];
+#endif
prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ;
len = ptoa((vm_offset_t)nr_pages);
- count = vm_fault_quick_hold_pages(map, start, len, prot, pages, nr_pages);
+ count = vm_fault_quick_hold_pages(map, start, len, prot, mpp, nr_pages);
+ free(mpp, M_KMALLOC);
return (count == -1 ? -EFAULT : nr_pages);
}
@@ -256,12 +345,13 @@
__get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct page **pages)
{
+ struct vm_page **mpp;
vm_map_t map;
vm_page_t *mp;
vm_offset_t va;
vm_offset_t end;
vm_prot_t prot;
- int count;
+ int count, i;
if (nr_pages == 0 || in_interrupt())
return (0);
@@ -272,7 +362,19 @@
if (!vm_map_range_valid(map, start, end))
return (-EINVAL);
prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ;
- for (count = 0, mp = pages, va = start; va < end;
+
+ mpp = malloc(sizeof(*mpp) * nr_pages, M_KMALLOC, M_NOWAIT|M_ZERO);
+ if (mpp == NULL)
+ return (-ENOMEM);
+
+ for (i = 0; i < nr_pages; i++)
+#ifdef PAGE_IS_LKPI_PAGE
+ mpp[i] = pages[i]->vm_page;
+#else
+ mpp[i] = pages[i];
+#endif
+ mp = mpp;
+ for (count = 0, va = start; va < end;
mp++, va += PAGE_SIZE, count++) {
*mp = pmap_extract_and_hold(map->pmap, va, prot);
if (*mp == NULL)
@@ -292,6 +394,8 @@
vm_page_dirty(*mp);
}
}
+ free(mpp, M_KMALLOC);
+
return (count);
}
@@ -415,15 +519,33 @@
void *
vmap(struct page **pages, unsigned int count, unsigned long flags, int prot)
{
+ struct vm_page **mpp;
vm_offset_t off;
size_t size;
+ int i;
+
+ mpp = malloc(sizeof(*mpp) * count, M_KMALLOC, M_NOWAIT|M_ZERO);
+ if (mpp == NULL)
+ return (NULL);
size = count * PAGE_SIZE;
off = kva_alloc(size);
- if (off == 0)
+ if (off == 0) {
+ free(mpp, M_KMALLOC);
return (NULL);
+ }
+
+ for (i = 0; i < count; i++)
+#ifdef PAGE_IS_LKPI_PAGE
+ mpp[i] = pages[i]->vm_page;
+#else
+ mpp[i] = pages[i];
+#endif
+
vmmap_add((void *)off, size);
- pmap_qenter(off, pages, count);
+ pmap_qenter(off, mpp, count);
+
+ free(mpp, M_KMALLOC);
return ((void *)off);
}
@@ -713,7 +835,7 @@
linuxkpi_page_frag_alloc(struct page_frag_cache *pfc,
size_t fragsz, gfp_t gfp)
{
- vm_page_t pages;
+ struct page *pages;
if (fragsz == 0)
return (NULL);
@@ -735,7 +857,7 @@
void
linuxkpi_page_frag_free(void *addr)
{
- vm_page_t page;
+ struct page *page;
page = virt_to_page(addr);
linux_free_pages(page, 0);
@@ -748,20 +870,78 @@
linux_free_pages(page, 0);
}
+#ifdef PAGE_IS_LKPI_PAGE
+/* -------------------------------------------------------------------------- */
+/*
+ * Mimic vm_page_array[] and similar logic dependent on PMAP_HAS_PAGE_ARRAY and
+ * VM_PHYSSEG_SPARSE or VM_PHYSSEG_DENSE for struct page essentially creating a
+ * shadow structure to keep Linux KPI specific information along native pages.
+ */
+
+static MALLOC_DEFINE(M_LKPI_PAGE, "lkpipage", "LinuxKPI page array");
+static struct page *lkpi_page_array;
+
+struct page *
+lkpi_vm_page_to_page(struct vm_page *m)
+{
+ struct vm_phys_seg *seg;
+ vm_paddr_t pa;
+ struct page *p;
+
+ MPASS(m != NULL);
+
+ pa = VM_PAGE_TO_PHYS(m);
+ seg = &vm_phys_segs[m->segind];
+ p = &lkpi_page_array[atop(pa - seg->start)];
+ // p->vm_page = m;
+ return (p);
+}
+
+struct page *
+linuxkpi_virt_to_page(const void *v)
+{
+ struct vm_page *m;
+
+ m = PHYS_TO_VM_PAGE(vtophys(v));
+ return (lkpi_vm_page_to_page(m));
+}
+
+/* pfn (page-frame number) to page. */
+struct page *
+linuxkpi_pfn_to_page(unsigned long pfn)
+{
+ struct vm_page *m;
+
+ m = PHYS_TO_VM_PAGE((pfn) << PAGE_SHIFT);
+ return (lkpi_vm_page_to_page(m));
+}
+
+/* -------------------------------------------------------------------------- */
+#endif
+
static void
-lkpi_page_init(void *arg)
+lkpi_page_init(void *arg __unused)
{
int i;
mtx_init(&vmmaplock, "IO Map lock", NULL, MTX_DEF);
for (i = 0; i < VMMAP_HASH_SIZE; i++)
LIST_INIT(&vmmaphead[i]);
+
+#ifdef PAGE_IS_LKPI_PAGE
+ lkpi_page_array = malloc(vm_page_array_size * sizeof(struct page),
+ M_LKPI_PAGE, M_WAITOK | M_ZERO);
+#endif
}
-SYSINIT(lkpi_page, SI_SUB_DRIVERS, SI_ORDER_SECOND, lkpi_page_init, NULL);
+SYSINIT(lkpi_page, SI_SUB_VM_CONF+1, SI_ORDER_ANY, lkpi_page_init, NULL);
static void
lkpi_page_uninit(void *arg)
{
mtx_destroy(&vmmaplock);
+
+#ifdef PAGE_IS_LKPI_PAGE
+ free(lkpi_page_array, M_LKPI_PAGE);
+#endif
}
-SYSUNINIT(lkpi_page, SI_SUB_DRIVERS, SI_ORDER_SECOND, lkpi_page_uninit, NULL);
+SYSUNINIT(lkpi_page, SI_SUB_VM_CONF+1, SI_ORDER_ANY, lkpi_page_uninit, NULL);
diff --git a/sys/compat/linuxkpi/common/src/linux_shmemfs.c b/sys/compat/linuxkpi/common/src/linux_shmemfs.c
--- a/sys/compat/linuxkpi/common/src/linux_shmemfs.c
+++ b/sys/compat/linuxkpi/common/src/linux_shmemfs.c
@@ -44,6 +44,7 @@
struct page *
linux_shmem_read_mapping_page_gfp(vm_object_t obj, int pindex, gfp_t gfp)
{
+ struct vm_page *m;
struct page *page;
int rv;
@@ -51,11 +52,16 @@
panic("GFP_NOWAIT is unimplemented");
VM_OBJECT_WLOCK(obj);
- rv = vm_page_grab_valid(&page, obj, pindex, VM_ALLOC_NORMAL |
+ rv = vm_page_grab_valid(&m, obj, pindex, VM_ALLOC_NORMAL |
VM_ALLOC_NOBUSY | VM_ALLOC_WIRED);
VM_OBJECT_WUNLOCK(obj);
if (rv != VM_PAGER_OK)
return (ERR_PTR(-EINVAL));
+#ifdef PAGE_IS_LKPI_PAGE
+ page = lkpi_vm_page_to_page(m);
+#else
+ page = m;
+#endif
return (page);
}
diff --git a/sys/dev/iser/iser_initiator.c b/sys/dev/iser/iser_initiator.c
--- a/sys/dev/iser/iser_initiator.c
+++ b/sys/dev/iser/iser_initiator.c
@@ -304,6 +304,7 @@
int i;
size_t len, tlen;
int offset;
+ struct page *page;
tlen = bp->bio_bcount;
offset = bp->bio_ma_offset;
@@ -311,7 +312,13 @@
for (i = 0; 0 < tlen; i++, tlen -= len) {
sg = &data_buf->sgl[i];
len = min(PAGE_SIZE - offset, tlen);
- sg_set_page(sg, bp->bio_ma[i], len, offset);
+#ifdef PAGE_IS_LKPI_PAGE
+ /* Fix this "abuse" feeding LinuxKPI a FreeBSD vm_page. */
+ page = lkpi_vm_page_to_page(bp->bio_ma[i]);
+#else
+ page = bp->bio_ma[i];
+#endif
+ sg_set_page(sg, page, len, offset);
offset = 0;
}

File Metadata

Mime Type
text/plain
Expires
Wed, Jul 15, 1:22 AM (18 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35069056
Default Alt Text
D53440.id.diff (17 KB)

Event Timeline