Print this page
use NULL capable segop as a shorthand for no-capabilities
Instead of forcing every segment driver to implement a dummy "return 0"
function, handle NULL capable segop function pointer as "no copabilities
supported" shorthand.


 116 static size_t   segvn_incore(struct seg *seg, caddr_t addr, size_t len,
 117                     char *vec);
 118 static int      segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
 119                     int attr, int op, ulong_t *lockmap, size_t pos);
 120 static int      segvn_getprot(struct seg *seg, caddr_t addr, size_t len,
 121                     uint_t *protv);
 122 static u_offset_t       segvn_getoffset(struct seg *seg, caddr_t addr);
 123 static int      segvn_gettype(struct seg *seg, caddr_t addr);
 124 static int      segvn_getvp(struct seg *seg, caddr_t addr,
 125                     struct vnode **vpp);
 126 static int      segvn_advise(struct seg *seg, caddr_t addr, size_t len,
 127                     uint_t behav);
 128 static void     segvn_dump(struct seg *seg);
 129 static int      segvn_pagelock(struct seg *seg, caddr_t addr, size_t len,
 130                     struct page ***ppp, enum lock_type type, enum seg_rw rw);
 131 static int      segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len,
 132                     uint_t szc);
 133 static int      segvn_getmemid(struct seg *seg, caddr_t addr,
 134                     memid_t *memidp);
 135 static lgrp_mem_policy_info_t   *segvn_getpolicy(struct seg *, caddr_t);
 136 static int      segvn_capable(struct seg *seg, segcapability_t capable);
 137 static int      segvn_inherit(struct seg *, caddr_t, size_t, uint_t);
 138 
 139 struct  seg_ops segvn_ops = {
 140         .dup            = segvn_dup,
 141         .unmap          = segvn_unmap,
 142         .free           = segvn_free,
 143         .fault          = segvn_fault,
 144         .faulta         = segvn_faulta,
 145         .setprot        = segvn_setprot,
 146         .checkprot      = segvn_checkprot,
 147         .kluster        = segvn_kluster,
 148         .sync           = segvn_sync,
 149         .incore         = segvn_incore,
 150         .lockop         = segvn_lockop,
 151         .getprot        = segvn_getprot,
 152         .getoffset      = segvn_getoffset,
 153         .gettype        = segvn_gettype,
 154         .getvp          = segvn_getvp,
 155         .advise         = segvn_advise,
 156         .dump           = segvn_dump,
 157         .pagelock       = segvn_pagelock,
 158         .setpagesize    = segvn_setpagesize,
 159         .getmemid       = segvn_getmemid,
 160         .getpolicy      = segvn_getpolicy,
 161         .capable        = segvn_capable,
 162         .inherit        = segvn_inherit,
 163 };
 164 
 165 /*
 166  * Common zfod structures, provided as a shorthand for others to use.
 167  */
 168 static segvn_crargs_t zfod_segvn_crargs =
 169         SEGVN_ZFOD_ARGS(PROT_ZFOD, PROT_ALL);
 170 static segvn_crargs_t kzfod_segvn_crargs =
 171         SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_USER,
 172         PROT_ALL & ~PROT_USER);
 173 static segvn_crargs_t stack_noexec_crargs =
 174         SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_EXEC, PROT_ALL);
 175 
 176 caddr_t zfod_argsp = (caddr_t)&zfod_segvn_crargs;   /* user zfod argsp */
 177 caddr_t kzfod_argsp = (caddr_t)&kzfod_segvn_crargs; /* kernel zfod argsp */
 178 caddr_t stack_exec_argsp = (caddr_t)&zfod_segvn_crargs;     /* executable stack */
 179 caddr_t stack_noexec_argsp = (caddr_t)&stack_noexec_crargs; /* noexec stack */
 180 
 181 #define vpgtob(n)       ((n) * sizeof (struct vpage))   /* For brevity */


9466         /*
9467          * Get policy info for private or shared memory
9468          */
9469         if (svn_data->type != MAP_SHARED) {
9470                 if (svn_data->tr_state != SEGVN_TR_ON) {
9471                         policy_info = &svn_data->policy_info;
9472                 } else {
9473                         policy_info = &svn_data->tr_policy_info;
9474                         ASSERT(policy_info->mem_policy ==
9475                             LGRP_MEM_POLICY_NEXT_SEG);
9476                 }
9477         } else {
9478                 amp = svn_data->amp;
9479                 anon_index = svn_data->anon_index + seg_page(seg, addr);
9480                 vp = svn_data->vp;
9481                 vn_off = svn_data->offset + (uintptr_t)(addr - seg->s_base);
9482                 policy_info = lgrp_shm_policy_get(amp, anon_index, vp, vn_off);
9483         }
9484 
9485         return (policy_info);
9486 }
9487 
9488 /*ARGSUSED*/
9489 static int
9490 segvn_capable(struct seg *seg, segcapability_t capability)
9491 {
9492         return (0);
9493 }
9494 
9495 /*
9496  * Bind text vnode segment to an amp. If we bind successfully mappings will be
9497  * established to per vnode mapping per lgroup amp pages instead of to vnode
9498  * pages. There's one amp per vnode text mapping per lgroup. Many processes
9499  * may share the same text replication amp. If a suitable amp doesn't already
9500  * exist in svntr hash table create a new one.  We may fail to bind to amp if
9501  * segment is not eligible for text replication.  Code below first checks for
9502  * these conditions. If binding is successful segment tr_state is set to on
9503  * and svd->amp points to the amp to use. Otherwise tr_state is set to off and
9504  * svd->amp remains as NULL.
9505  */
9506 static void
9507 segvn_textrepl(struct seg *seg)
9508 {
9509         struct segvn_data       *svd = (struct segvn_data *)seg->s_data;
9510         vnode_t                 *vp = svd->vp;
9511         u_offset_t              off = svd->offset;
9512         size_t                  size = seg->s_size;




 116 static size_t   segvn_incore(struct seg *seg, caddr_t addr, size_t len,
 117                     char *vec);
 118 static int      segvn_lockop(struct seg *seg, caddr_t addr, size_t len,
 119                     int attr, int op, ulong_t *lockmap, size_t pos);
 120 static int      segvn_getprot(struct seg *seg, caddr_t addr, size_t len,
 121                     uint_t *protv);
 122 static u_offset_t       segvn_getoffset(struct seg *seg, caddr_t addr);
 123 static int      segvn_gettype(struct seg *seg, caddr_t addr);
 124 static int      segvn_getvp(struct seg *seg, caddr_t addr,
 125                     struct vnode **vpp);
 126 static int      segvn_advise(struct seg *seg, caddr_t addr, size_t len,
 127                     uint_t behav);
 128 static void     segvn_dump(struct seg *seg);
 129 static int      segvn_pagelock(struct seg *seg, caddr_t addr, size_t len,
 130                     struct page ***ppp, enum lock_type type, enum seg_rw rw);
 131 static int      segvn_setpagesize(struct seg *seg, caddr_t addr, size_t len,
 132                     uint_t szc);
 133 static int      segvn_getmemid(struct seg *seg, caddr_t addr,
 134                     memid_t *memidp);
 135 static lgrp_mem_policy_info_t   *segvn_getpolicy(struct seg *, caddr_t);

 136 static int      segvn_inherit(struct seg *, caddr_t, size_t, uint_t);
 137 
 138 struct  seg_ops segvn_ops = {
 139         .dup            = segvn_dup,
 140         .unmap          = segvn_unmap,
 141         .free           = segvn_free,
 142         .fault          = segvn_fault,
 143         .faulta         = segvn_faulta,
 144         .setprot        = segvn_setprot,
 145         .checkprot      = segvn_checkprot,
 146         .kluster        = segvn_kluster,
 147         .sync           = segvn_sync,
 148         .incore         = segvn_incore,
 149         .lockop         = segvn_lockop,
 150         .getprot        = segvn_getprot,
 151         .getoffset      = segvn_getoffset,
 152         .gettype        = segvn_gettype,
 153         .getvp          = segvn_getvp,
 154         .advise         = segvn_advise,
 155         .dump           = segvn_dump,
 156         .pagelock       = segvn_pagelock,
 157         .setpagesize    = segvn_setpagesize,
 158         .getmemid       = segvn_getmemid,
 159         .getpolicy      = segvn_getpolicy,

 160         .inherit        = segvn_inherit,
 161 };
 162 
 163 /*
 164  * Common zfod structures, provided as a shorthand for others to use.
 165  */
 166 static segvn_crargs_t zfod_segvn_crargs =
 167         SEGVN_ZFOD_ARGS(PROT_ZFOD, PROT_ALL);
 168 static segvn_crargs_t kzfod_segvn_crargs =
 169         SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_USER,
 170         PROT_ALL & ~PROT_USER);
 171 static segvn_crargs_t stack_noexec_crargs =
 172         SEGVN_ZFOD_ARGS(PROT_ZFOD & ~PROT_EXEC, PROT_ALL);
 173 
 174 caddr_t zfod_argsp = (caddr_t)&zfod_segvn_crargs;   /* user zfod argsp */
 175 caddr_t kzfod_argsp = (caddr_t)&kzfod_segvn_crargs; /* kernel zfod argsp */
 176 caddr_t stack_exec_argsp = (caddr_t)&zfod_segvn_crargs;     /* executable stack */
 177 caddr_t stack_noexec_argsp = (caddr_t)&stack_noexec_crargs; /* noexec stack */
 178 
 179 #define vpgtob(n)       ((n) * sizeof (struct vpage))   /* For brevity */


9464         /*
9465          * Get policy info for private or shared memory
9466          */
9467         if (svn_data->type != MAP_SHARED) {
9468                 if (svn_data->tr_state != SEGVN_TR_ON) {
9469                         policy_info = &svn_data->policy_info;
9470                 } else {
9471                         policy_info = &svn_data->tr_policy_info;
9472                         ASSERT(policy_info->mem_policy ==
9473                             LGRP_MEM_POLICY_NEXT_SEG);
9474                 }
9475         } else {
9476                 amp = svn_data->amp;
9477                 anon_index = svn_data->anon_index + seg_page(seg, addr);
9478                 vp = svn_data->vp;
9479                 vn_off = svn_data->offset + (uintptr_t)(addr - seg->s_base);
9480                 policy_info = lgrp_shm_policy_get(amp, anon_index, vp, vn_off);
9481         }
9482 
9483         return (policy_info);







9484 }
9485 
9486 /*
9487  * Bind text vnode segment to an amp. If we bind successfully mappings will be
9488  * established to per vnode mapping per lgroup amp pages instead of to vnode
9489  * pages. There's one amp per vnode text mapping per lgroup. Many processes
9490  * may share the same text replication amp. If a suitable amp doesn't already
9491  * exist in svntr hash table create a new one.  We may fail to bind to amp if
9492  * segment is not eligible for text replication.  Code below first checks for
9493  * these conditions. If binding is successful segment tr_state is set to on
9494  * and svd->amp points to the amp to use. Otherwise tr_state is set to off and
9495  * svd->amp remains as NULL.
9496  */
9497 static void
9498 segvn_textrepl(struct seg *seg)
9499 {
9500         struct segvn_data       *svd = (struct segvn_data *)seg->s_data;
9501         vnode_t                 *vp = svd->vp;
9502         u_offset_t              off = svd->offset;
9503         size_t                  size = seg->s_size;