1620 * and for kernel startup to attach to static segments.
1621 */
1622 int
1623 seg_attach(struct as *as, caddr_t base, size_t size, struct seg *seg)
1624 {
1625 seg->s_as = as;
1626 seg->s_base = base;
1627 seg->s_size = size;
1628
1629 /*
1630 * as_addseg() will add the segment at the appropraite point
1631 * in the list. It will return -1 if there is overlap with
1632 * an already existing segment.
1633 */
1634 return (as_addseg(as, seg));
1635 }
1636
1637 /*
1638 * Unmap a segment and free it from its associated address space.
1639 * This should be called by anybody who's finished with a whole segment's
1640 * mapping. Just calls SEGOP_UNMAP() on the whole mapping . It is the
1641 * responsibility of the segment driver to unlink the the segment
1642 * from the address space, and to free public and private data structures
1643 * associated with the segment. (This is typically done by a call to
1644 * seg_free()).
1645 */
1646 void
1647 seg_unmap(struct seg *seg)
1648 {
1649 #ifdef DEBUG
1650 int ret;
1651 #endif /* DEBUG */
1652
1653 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
1654
1655 /* Shouldn't have called seg_unmap if mapping isn't yet established */
1656 ASSERT(seg->s_data != NULL);
1657
1658 /* Unmap the whole mapping */
1659 #ifdef DEBUG
1660 ret = SEGOP_UNMAP(seg, seg->s_base, seg->s_size);
1661 ASSERT(ret == 0);
1662 #else
1663 SEGOP_UNMAP(seg, seg->s_base, seg->s_size);
1664 #endif /* DEBUG */
1665 }
1666
1667 /*
1668 * Free the segment from its associated as. This should only be called
1669 * if a mapping to the segment has not yet been established (e.g., if
1670 * an error occurs in the middle of doing an as_map when the segment
1671 * has already been partially set up) or if it has already been deleted
1672 * (e.g., from a segment driver unmap routine if the unmap applies to the
1673 * entire segment). If the mapping is currently set up then seg_unmap() should
1674 * be called instead.
1675 */
1676 void
1677 seg_free(struct seg *seg)
1678 {
1679 register struct as *as = seg->s_as;
1680 struct seg *tseg = as_removeseg(as, seg);
1681
1682 ASSERT(tseg == seg);
1683
1684 /*
1685 * If the segment private data field is NULL,
1686 * then segment driver is not attached yet.
1687 */
1688 if (seg->s_data != NULL)
1689 SEGOP_FREE(seg);
1690
1691 mutex_destroy(&seg->s_pmtx);
1692 ASSERT(seg->s_phead.p_lnext == &seg->s_phead);
1693 ASSERT(seg->s_phead.p_lprev == &seg->s_phead);
1694 kmem_cache_free(seg_cache, seg);
1695 }
1696
1697 /*ARGSUSED*/
1698 static void
1699 seg_p_mem_config_post_add(
1700 void *arg,
1701 pgcnt_t delta_pages)
1702 {
1703 /* Nothing to do. */
1704 }
1705
1706 void
1707 seg_p_enable(void)
1708 {
1709 mutex_enter(&seg_pcache_mtx);
1838 }
1839
1840 /*
1841 * Return swap reserved by a segment backing a private mapping.
1842 */
1843 size_t
1844 seg_swresv(struct seg *seg)
1845 {
1846 struct segvn_data *svd;
1847 size_t swap = 0;
1848
1849 if (seg->s_ops == &segvn_ops) {
1850 svd = (struct segvn_data *)seg->s_data;
1851 if (svd->type == MAP_PRIVATE && svd->swresv > 0)
1852 swap = svd->swresv;
1853 }
1854 return (swap);
1855 }
1856
1857 /*
1858 * General not supported function for SEGOP_INHERIT
1859 */
1860 /* ARGSUSED */
1861 int
1862 seg_inherit_notsup(struct seg *seg, caddr_t addr, size_t len, uint_t op)
1863 {
1864 return (ENOTSUP);
1865 }
1866
1867 /*
1868 * segop wrappers
1869 */
1870 int
1871 segop_dup(struct seg *seg, struct seg *new)
1872 {
1873 return (seg->s_ops->dup(seg, new));
1874 }
1875
1876 int
1877 segop_unmap(struct seg *seg, caddr_t addr, size_t len)
1878 {
|
1620 * and for kernel startup to attach to static segments.
1621 */
1622 int
1623 seg_attach(struct as *as, caddr_t base, size_t size, struct seg *seg)
1624 {
1625 seg->s_as = as;
1626 seg->s_base = base;
1627 seg->s_size = size;
1628
1629 /*
1630 * as_addseg() will add the segment at the appropraite point
1631 * in the list. It will return -1 if there is overlap with
1632 * an already existing segment.
1633 */
1634 return (as_addseg(as, seg));
1635 }
1636
1637 /*
1638 * Unmap a segment and free it from its associated address space.
1639 * This should be called by anybody who's finished with a whole segment's
1640 * mapping. Just calls segop_unmap() on the whole mapping . It is the
1641 * responsibility of the segment driver to unlink the the segment
1642 * from the address space, and to free public and private data structures
1643 * associated with the segment. (This is typically done by a call to
1644 * seg_free()).
1645 */
1646 void
1647 seg_unmap(struct seg *seg)
1648 {
1649 #ifdef DEBUG
1650 int ret;
1651 #endif /* DEBUG */
1652
1653 ASSERT(seg->s_as && AS_WRITE_HELD(seg->s_as, &seg->s_as->a_lock));
1654
1655 /* Shouldn't have called seg_unmap if mapping isn't yet established */
1656 ASSERT(seg->s_data != NULL);
1657
1658 /* Unmap the whole mapping */
1659 #ifdef DEBUG
1660 ret = segop_unmap(seg, seg->s_base, seg->s_size);
1661 ASSERT(ret == 0);
1662 #else
1663 (void) segop_unmap(seg, seg->s_base, seg->s_size);
1664 #endif /* DEBUG */
1665 }
1666
1667 /*
1668 * Free the segment from its associated as. This should only be called
1669 * if a mapping to the segment has not yet been established (e.g., if
1670 * an error occurs in the middle of doing an as_map when the segment
1671 * has already been partially set up) or if it has already been deleted
1672 * (e.g., from a segment driver unmap routine if the unmap applies to the
1673 * entire segment). If the mapping is currently set up then seg_unmap() should
1674 * be called instead.
1675 */
1676 void
1677 seg_free(struct seg *seg)
1678 {
1679 register struct as *as = seg->s_as;
1680 struct seg *tseg = as_removeseg(as, seg);
1681
1682 ASSERT(tseg == seg);
1683
1684 /*
1685 * If the segment private data field is NULL,
1686 * then segment driver is not attached yet.
1687 */
1688 if (seg->s_data != NULL)
1689 segop_free(seg);
1690
1691 mutex_destroy(&seg->s_pmtx);
1692 ASSERT(seg->s_phead.p_lnext == &seg->s_phead);
1693 ASSERT(seg->s_phead.p_lprev == &seg->s_phead);
1694 kmem_cache_free(seg_cache, seg);
1695 }
1696
1697 /*ARGSUSED*/
1698 static void
1699 seg_p_mem_config_post_add(
1700 void *arg,
1701 pgcnt_t delta_pages)
1702 {
1703 /* Nothing to do. */
1704 }
1705
1706 void
1707 seg_p_enable(void)
1708 {
1709 mutex_enter(&seg_pcache_mtx);
1838 }
1839
1840 /*
1841 * Return swap reserved by a segment backing a private mapping.
1842 */
1843 size_t
1844 seg_swresv(struct seg *seg)
1845 {
1846 struct segvn_data *svd;
1847 size_t swap = 0;
1848
1849 if (seg->s_ops == &segvn_ops) {
1850 svd = (struct segvn_data *)seg->s_data;
1851 if (svd->type == MAP_PRIVATE && svd->swresv > 0)
1852 swap = svd->swresv;
1853 }
1854 return (swap);
1855 }
1856
1857 /*
1858 * General not supported function for segop_inherit
1859 */
1860 /* ARGSUSED */
1861 int
1862 seg_inherit_notsup(struct seg *seg, caddr_t addr, size_t len, uint_t op)
1863 {
1864 return (ENOTSUP);
1865 }
1866
1867 /*
1868 * segop wrappers
1869 */
1870 int
1871 segop_dup(struct seg *seg, struct seg *new)
1872 {
1873 return (seg->s_ops->dup(seg, new));
1874 }
1875
1876 int
1877 segop_unmap(struct seg *seg, caddr_t addr, size_t len)
1878 {
|