seg_kmem.c (e57e118b) seg_kmem.c (04909c8c)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 108 unchanged lines hidden (view full) ---

117vmem_t *heaptext_arena; /* heaptext arena */
118struct as kas; /* kernel address space */
119int segkmem_reloc; /* enable/disable relocatable segkmem pages */
120vmem_t *static_arena; /* arena for caches to import static memory */
121vmem_t *static_alloc_arena; /* arena for allocating static memory */
122vmem_t *zio_arena = NULL; /* arena for allocating zio memory */
123vmem_t *zio_alloc_arena = NULL; /* arena for allocating zio memory */
124
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 108 unchanged lines hidden (view full) ---

117vmem_t *heaptext_arena; /* heaptext arena */
118struct as kas; /* kernel address space */
119int segkmem_reloc; /* enable/disable relocatable segkmem pages */
120vmem_t *static_arena; /* arena for caches to import static memory */
121vmem_t *static_alloc_arena; /* arena for allocating static memory */
122vmem_t *zio_arena = NULL; /* arena for allocating zio memory */
123vmem_t *zio_alloc_arena = NULL; /* arena for allocating zio memory */
124
125#if defined(__amd64)
126vmem_t *kvmm_arena; /* arena for vmm VA */
127struct seg kvmmseg; /* Segment for vmm memory */
128#endif
129
125/*
126 * seg_kmem driver can map part of the kernel heap with large pages.
127 * Currently this functionality is implemented for sparc platforms only.
128 *
129 * The large page size "segkmem_lpsize" for kernel heap is selected in the
130 * platform specific code. It can also be modified via /etc/system file.
131 * Setting segkmem_lpsize to PAGESIZE in /etc/system disables usage of large
132 * pages for kernel heap. "segkmem_lpshift" is adjusted appropriately to

--- 517 unchanged lines hidden (view full) ---

650 } else if (seg == &kvseg_core) {
651 vmem_walk(heap_core_arena, VMEM_ALLOC | VMEM_REENTRANT,
652 segkmem_dump_range, seg->s_as);
653 } else if (seg == &kvseg32) {
654 vmem_walk(heap32_arena, VMEM_ALLOC | VMEM_REENTRANT,
655 segkmem_dump_range, seg->s_as);
656 vmem_walk(heaptext_arena, VMEM_ALLOC | VMEM_REENTRANT,
657 segkmem_dump_range, seg->s_as);
130/*
131 * seg_kmem driver can map part of the kernel heap with large pages.
132 * Currently this functionality is implemented for sparc platforms only.
133 *
134 * The large page size "segkmem_lpsize" for kernel heap is selected in the
135 * platform specific code. It can also be modified via /etc/system file.
136 * Setting segkmem_lpsize to PAGESIZE in /etc/system disables usage of large
137 * pages for kernel heap. "segkmem_lpshift" is adjusted appropriately to

--- 517 unchanged lines hidden (view full) ---

655 } else if (seg == &kvseg_core) {
656 vmem_walk(heap_core_arena, VMEM_ALLOC | VMEM_REENTRANT,
657 segkmem_dump_range, seg->s_as);
658 } else if (seg == &kvseg32) {
659 vmem_walk(heap32_arena, VMEM_ALLOC | VMEM_REENTRANT,
660 segkmem_dump_range, seg->s_as);
661 vmem_walk(heaptext_arena, VMEM_ALLOC | VMEM_REENTRANT,
662 segkmem_dump_range, seg->s_as);
663 /*
664 * We don't want to dump pages attached to kzioseg since they
665 * contain file data from ZFS. If this page's segment is
666 * kzioseg return instead of writing it to the dump device.
667 *
668 * Same applies to VM memory allocations.
669 */
658 } else if (seg == &kzioseg) {
670 } else if (seg == &kzioseg) {
659 /*
660 * We don't want to dump pages attached to kzioseg since they
661 * contain file data from ZFS. If this page's segment is
662 * kzioseg return instead of writing it to the dump device.
663 */
664 return;
671 return;
672#if defined(__amd64)
673 } else if (seg == &kvmmseg) {
674 return;
675#endif
665 } else {
666 segkmem_dump_range(seg->s_as, seg->s_base, seg->s_size);
667 }
668}
669
670/*
671 * lock/unlock kmem pages over a given range [addr, addr+len).
672 * Returns a shadow list of pages in ppp. If there are holes

--- 124 unchanged lines hidden (view full) ---

797 SEGKMEM_BADOP(int), /* setpgsz */
798 segkmem_getmemid,
799 segkmem_getpolicy, /* getpolicy */
800 segkmem_capable, /* capable */
801 seg_inherit_notsup /* inherit */
802};
803
804int
676 } else {
677 segkmem_dump_range(seg->s_as, seg->s_base, seg->s_size);
678 }
679}
680
681/*
682 * lock/unlock kmem pages over a given range [addr, addr+len).
683 * Returns a shadow list of pages in ppp. If there are holes

--- 124 unchanged lines hidden (view full) ---

808 SEGKMEM_BADOP(int), /* setpgsz */
809 segkmem_getmemid,
810 segkmem_getpolicy, /* getpolicy */
811 segkmem_capable, /* capable */
812 seg_inherit_notsup /* inherit */
813};
814
815int
805segkmem_zio_create(struct seg *seg)
806{
807 ASSERT(seg->s_as == &kas && RW_WRITE_HELD(&kas.a_lock));
808 seg->s_ops = &segkmem_ops;
809 seg->s_data = &zvp;
810 kas.a_size += seg->s_size;
811 return (0);
812}
813
814int
815segkmem_create(struct seg *seg)
816{
817 ASSERT(seg->s_as == &kas && RW_WRITE_HELD(&kas.a_lock));
818 seg->s_ops = &segkmem_ops;
816segkmem_create(struct seg *seg)
817{
818 ASSERT(seg->s_as == &kas && RW_WRITE_HELD(&kas.a_lock));
819 seg->s_ops = &segkmem_ops;
819 seg->s_data = &kvp;
820 if (seg == &kzioseg)
821 seg->s_data = &kvps[KV_ZVP];
822#if defined(__amd64)
823 else if (seg == &kvmmseg)
824 seg->s_data = &kvps[KV_VVP];
825#endif
826 else
827 seg->s_data = &kvps[KV_KVP];
820 kas.a_size += seg->s_size;
821 return (0);
822}
823
824/*ARGSUSED*/
825page_t *
826segkmem_page_create(void *addr, size_t size, int vmflag, void *arg)
827{

--- 134 unchanged lines hidden (view full) ---

962}
963
964void *
965segkmem_alloc(vmem_t *vmp, size_t size, int vmflag)
966{
967 return (segkmem_alloc_vn(vmp, size, vmflag, &kvp));
968}
969
828 kas.a_size += seg->s_size;
829 return (0);
830}
831
832/*ARGSUSED*/
833page_t *
834segkmem_page_create(void *addr, size_t size, int vmflag, void *arg)
835{

--- 134 unchanged lines hidden (view full) ---

970}
971
972void *
973segkmem_alloc(vmem_t *vmp, size_t size, int vmflag)
974{
975 return (segkmem_alloc_vn(vmp, size, vmflag, &kvp));
976}
977
970void *
978static void *
971segkmem_zio_alloc(vmem_t *vmp, size_t size, int vmflag)
972{
979segkmem_zio_alloc(vmem_t *vmp, size_t size, int vmflag)
980{
973 return (segkmem_alloc_vn(vmp, size, vmflag, &zvp));
981 return (segkmem_alloc_vn(vmp, size, vmflag, &kvps[KV_ZVP]));
974}
975
976/*
977 * Any changes to this routine must also be carried over to
978 * devmap_free_pages() in the seg_dev driver. This is because
979 * we currently don't have a special kernel segment for non-paged
980 * kernel memory that is exported by drivers to user space.
981 */
982}
983
984/*
985 * Any changes to this routine must also be carried over to
986 * devmap_free_pages() in the seg_dev driver. This is because
987 * we currently don't have a special kernel segment for non-paged
988 * kernel memory that is exported by drivers to user space.
989 */
982static void
983segkmem_free_vn(vmem_t *vmp, void *inaddr, size_t size, struct vnode *vp,
990void
991segkmem_xfree(vmem_t *vmp, void *inaddr, size_t size, struct vnode *vp,
984 void (*func)(page_t *))
985{
986 page_t *pp;
987 caddr_t addr = inaddr;
988 caddr_t eaddr;
989 pgcnt_t npages = btopr(size);
990
991 ASSERT(((uintptr_t)addr & PAGEOFFSET) == 0);

--- 40 unchanged lines hidden (view full) ---

1032 page_unresv(npages);
1033
1034 if (vmp != NULL)
1035 vmem_free(vmp, inaddr, size);
1036
1037}
1038
1039void
992 void (*func)(page_t *))
993{
994 page_t *pp;
995 caddr_t addr = inaddr;
996 caddr_t eaddr;
997 pgcnt_t npages = btopr(size);
998
999 ASSERT(((uintptr_t)addr & PAGEOFFSET) == 0);

--- 40 unchanged lines hidden (view full) ---

1040 page_unresv(npages);
1041
1042 if (vmp != NULL)
1043 vmem_free(vmp, inaddr, size);
1044
1045}
1046
1047void
1040segkmem_xfree(vmem_t *vmp, void *inaddr, size_t size, void (*func)(page_t *))
1041{
1042 segkmem_free_vn(vmp, inaddr, size, &kvp, func);
1043}
1044
1045void
1046segkmem_free(vmem_t *vmp, void *inaddr, size_t size)
1047{
1048segkmem_free(vmem_t *vmp, void *inaddr, size_t size)
1049{
1048 segkmem_free_vn(vmp, inaddr, size, &kvp, NULL);
1050 segkmem_xfree(vmp, inaddr, size, &kvp, NULL);
1049}
1050
1051}
1052
1051void
1053static void
1052segkmem_zio_free(vmem_t *vmp, void *inaddr, size_t size)
1053{
1054segkmem_zio_free(vmem_t *vmp, void *inaddr, size_t size)
1055{
1054 segkmem_free_vn(vmp, inaddr, size, &zvp, NULL);
1056 segkmem_xfree(vmp, inaddr, size, &kvps[KV_ZVP], NULL);
1055}
1056
1057void
1058segkmem_gc(void)
1059{
1060 ASSERT(kvseg.s_base != NULL);
1061 while (segkmem_gc_list != NULL) {
1062 segkmem_gc_list_t *gc = segkmem_gc_list;

--- 465 unchanged lines hidden (view full) ---

1528
1529 zio_alloc_arena = vmem_create("zfs_file_data_buf", NULL, 0, PAGESIZE,
1530 segkmem_zio_alloc, segkmem_zio_free, zio_arena, 0, VM_SLEEP);
1531
1532 ASSERT(zio_arena != NULL);
1533 ASSERT(zio_alloc_arena != NULL);
1534}
1535
1057}
1058
1059void
1060segkmem_gc(void)
1061{
1062 ASSERT(kvseg.s_base != NULL);
1063 while (segkmem_gc_list != NULL) {
1064 segkmem_gc_list_t *gc = segkmem_gc_list;

--- 465 unchanged lines hidden (view full) ---

1530
1531 zio_alloc_arena = vmem_create("zfs_file_data_buf", NULL, 0, PAGESIZE,
1532 segkmem_zio_alloc, segkmem_zio_free, zio_arena, 0, VM_SLEEP);
1533
1534 ASSERT(zio_arena != NULL);
1535 ASSERT(zio_alloc_arena != NULL);
1536}
1537
1536#ifdef __sparc
1538#if defined(__amd64)
1537
1539
1540void
1541segkmem_kvmm_init(void *base, size_t size)
1542{
1543 ASSERT(base != NULL);
1544 ASSERT(size != 0);
1538
1545
1546 kvmm_arena = vmem_create("kvmm_arena", base, size, 1024 * 1024,
1547 NULL, NULL, NULL, 0, VM_SLEEP);
1548
1549 ASSERT(kvmm_arena != NULL);
1550}
1551
1552#elif defined(__sparc)
1553
1539static void *
1540segkmem_alloc_ppa(vmem_t *vmp, size_t size, int vmflag)
1541{
1542 size_t ppaquantum = btopr(segkmem_lpsize) * sizeof (page_t *);
1543 void *addr;
1544
1545 if (ppaquantum <= PAGESIZE)
1546 return (segkmem_alloc(vmp, size, vmflag));

--- 98 unchanged lines hidden ---
1554static void *
1555segkmem_alloc_ppa(vmem_t *vmp, size_t size, int vmflag)
1556{
1557 size_t ppaquantum = btopr(segkmem_lpsize) * sizeof (page_t *);
1558 void *addr;
1559
1560 if (ppaquantum <= PAGESIZE)
1561 return (segkmem_alloc(vmp, size, vmflag));

--- 98 unchanged lines hidden ---