Print this page
patch as-lock-macro-simplification

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/proc/prioctl.c
          +++ new/usr/src/uts/common/fs/proc/prioctl.c
↓ open down ↓ 954 lines elided ↑ open up ↑
 955  955  
 956  956          case PIOCNMAP:          /* get number of memory mappings */
 957  957          {
 958  958                  int n;
 959  959                  struct as *as = p->p_as;
 960  960  
 961  961                  if ((p->p_flag & SSYS) || as == &kas)
 962  962                          n = 0;
 963  963                  else {
 964  964                          mutex_exit(&p->p_lock);
 965      -                        AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
      965 +                        AS_LOCK_ENTER(as, RW_WRITER);
 966  966                          n = prnsegs(as, 0);
 967      -                        AS_LOCK_EXIT(as, &as->a_lock);
      967 +                        AS_LOCK_EXIT(as);
 968  968                          mutex_enter(&p->p_lock);
 969  969                  }
 970  970                  prunlock(pnp);
 971  971                  if (copyout(&n, cmaddr, sizeof (int)))
 972  972                          error = EFAULT;
 973  973                  break;
 974  974          }
 975  975  
 976  976          case PIOCMAP:           /* get memory map information */
 977  977          {
 978  978                  list_t iolhead;
 979  979                  struct as *as = p->p_as;
 980  980  
 981  981                  if ((p->p_flag & SSYS) || as == &kas) {
 982  982                          error = 0;
 983  983                          prunlock(pnp);
 984  984                  } else {
 985  985                          mutex_exit(&p->p_lock);
 986      -                        AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
      986 +                        AS_LOCK_ENTER(as, RW_WRITER);
 987  987                          error = oprgetmap(p, &iolhead);
 988      -                        AS_LOCK_EXIT(as, &as->a_lock);
      988 +                        AS_LOCK_EXIT(as);
 989  989                          mutex_enter(&p->p_lock);
 990  990                          prunlock(pnp);
 991  991  
 992  992                          error = pr_iol_copyout_and_free(&iolhead,
 993  993                              &cmaddr, error);
 994  994                  }
 995  995                  /*
 996  996                   * The procfs PIOCMAP ioctl returns an all-zero buffer
 997  997                   * to indicate the end of the prmap[] array.
 998  998                   * Append it to whatever has already been copied out.
↓ open down ↓ 651 lines elided ↑ open up ↑
1650 1650                  psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */
1651 1651                  if (psp->pr_cpu > 99)
1652 1652                          psp->pr_cpu = 99;
1653 1653  
1654 1654                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
1655 1655                          psp->pr_size = 0;
1656 1656                          psp->pr_rssize = 0;
1657 1657                          psp->pr_pctmem = 0;
1658 1658                  } else {
1659 1659                          mutex_exit(&p->p_lock);
1660      -                        AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
     1660 +                        AS_LOCK_ENTER(as, RW_READER);
1661 1661                          psp->pr_size = (size32_t)btopr(as->a_resvsize);
1662 1662                          psp->pr_rssize = (size32_t)rm_asrss(as);
1663 1663                          psp->pr_pctmem = rm_pctmemory(as);
1664      -                        AS_LOCK_EXIT(as, &as->a_lock);
     1664 +                        AS_LOCK_EXIT(as);
1665 1665                          mutex_enter(&p->p_lock);
1666 1666                  }
1667 1667          }
1668 1668          psp->pr_bysize = (size32_t)ptob(psp->pr_size);
1669 1669          psp->pr_byrssize = (size32_t)ptob(psp->pr_rssize);
1670 1670  
1671 1671          /*
1672 1672           * If we are looking at an LP64 process, zero out
1673 1673           * the fields that cannot be represented in ILP32.
1674 1674           */
↓ open down ↓ 907 lines elided ↑ open up ↑
2582 2582  
2583 2583          case PIOCNMAP:          /* get number of memory mappings */
2584 2584          {
2585 2585                  int n;
2586 2586                  struct as *as = p->p_as;
2587 2587  
2588 2588                  if ((p->p_flag & SSYS) || as == &kas)
2589 2589                          n = 0;
2590 2590                  else {
2591 2591                          mutex_exit(&p->p_lock);
2592      -                        AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
     2592 +                        AS_LOCK_ENTER(as, RW_WRITER);
2593 2593                          n = prnsegs(as, 0);
2594      -                        AS_LOCK_EXIT(as, &as->a_lock);
     2594 +                        AS_LOCK_EXIT(as);
2595 2595                          mutex_enter(&p->p_lock);
2596 2596                  }
2597 2597                  prunlock(pnp);
2598 2598                  if (copyout(&n, cmaddr, sizeof (int)))
2599 2599                          error = EFAULT;
2600 2600                  break;
2601 2601          }
2602 2602  
2603 2603          case PIOCMAP:           /* get memory map information */
2604 2604          {
↓ open down ↓ 1 lines elided ↑ open up ↑
2606 2606                  struct as *as = p->p_as;
2607 2607  
2608 2608                  if ((p->p_flag & SSYS) || as == &kas) {
2609 2609                          error = 0;
2610 2610                          prunlock(pnp);
2611 2611                  } else if (PROCESS_NOT_32BIT(p)) {
2612 2612                          error = EOVERFLOW;
2613 2613                          prunlock(pnp);
2614 2614                  } else {
2615 2615                          mutex_exit(&p->p_lock);
2616      -                        AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
     2616 +                        AS_LOCK_ENTER(as, RW_WRITER);
2617 2617                          error = oprgetmap32(p, &iolhead);
2618      -                        AS_LOCK_EXIT(as, &as->a_lock);
     2618 +                        AS_LOCK_EXIT(as);
2619 2619                          mutex_enter(&p->p_lock);
2620 2620                          prunlock(pnp);
2621 2621  
2622 2622                          error = pr_iol_copyout_and_free(&iolhead,
2623 2623                              &cmaddr, error);
2624 2624                  }
2625 2625                  /*
2626 2626                   * The procfs PIOCMAP ioctl returns an all-zero buffer
2627 2627                   * to indicate the end of the prmap[] array.
2628 2628                   * Append it to whatever has already been copied out.
↓ open down ↓ 506 lines elided ↑ open up ↑
3135 3135                  error = EINVAL;
3136 3136          } else if (cmaddr) {
3137 3137                  /*
3138 3138                   * We drop p_lock before grabbing the address
3139 3139                   * space lock in order to avoid a deadlock with
3140 3140                   * the clock thread.  The process will not
3141 3141                   * disappear and its address space will not
3142 3142                   * change because it is marked P_PR_LOCK.
3143 3143                   */
3144 3144                  mutex_exit(&p->p_lock);
3145      -                AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
     3145 +                AS_LOCK_ENTER(as, RW_READER);
3146 3146                  seg = as_segat(as, va);
3147 3147                  if (seg != NULL &&
3148 3148                      seg->s_ops == &segvn_ops &&
3149 3149                      SEGOP_GETVP(seg, va, &xvp) == 0 &&
3150 3150                      xvp != NULL &&
3151 3151                      xvp->v_type == VREG) {
3152 3152                          VN_HOLD(xvp);
3153 3153                  } else {
3154 3154                          error = EINVAL;
3155 3155                  }
3156      -                AS_LOCK_EXIT(as, &as->a_lock);
     3156 +                AS_LOCK_EXIT(as);
3157 3157                  mutex_enter(&p->p_lock);
3158 3158          } else if ((xvp = p->p_exec) == NULL) {
3159 3159                  error = EINVAL;
3160 3160          } else {
3161 3161                  VN_HOLD(xvp);
3162 3162          }
3163 3163  
3164 3164          prunlock(pnp);
3165 3165  
3166 3166          if (error == 0) {
↓ open down ↓ 322 lines elided ↑ open up ↑
3489 3489                  psp->pr_cpu = (psp->pr_pctcpu*100 + 0x6000) >> 15; /* [0..99] */
3490 3490                  if (psp->pr_cpu > 99)
3491 3491                          psp->pr_cpu = 99;
3492 3492  
3493 3493                  if ((p->p_flag & SSYS) || (as = p->p_as) == &kas) {
3494 3494                          psp->pr_size = 0;
3495 3495                          psp->pr_rssize = 0;
3496 3496                          psp->pr_pctmem = 0;
3497 3497                  } else {
3498 3498                          mutex_exit(&p->p_lock);
3499      -                        AS_LOCK_ENTER(as, &as->a_lock, RW_READER);
     3499 +                        AS_LOCK_ENTER(as, RW_READER);
3500 3500                          psp->pr_size = btopr(as->a_resvsize);
3501 3501                          psp->pr_rssize = rm_asrss(as);
3502 3502                          psp->pr_pctmem = rm_pctmemory(as);
3503      -                        AS_LOCK_EXIT(as, &as->a_lock);
     3503 +                        AS_LOCK_EXIT(as);
3504 3504                          mutex_enter(&p->p_lock);
3505 3505                  }
3506 3506          }
3507 3507          psp->pr_bysize = ptob(psp->pr_size);
3508 3508          psp->pr_byrssize = ptob(psp->pr_rssize);
3509 3509  }
3510 3510  
3511 3511  /*
3512 3512   * Return an array of structures with memory map information.
3513 3513   * We allocate here; the caller must deallocate.
↓ open down ↓ 2 lines elided ↑ open up ↑
3516 3516   */
3517 3517  static int
3518 3518  oprgetmap(proc_t *p, list_t *iolhead)
3519 3519  {
3520 3520          struct as *as = p->p_as;
3521 3521          prmap_t *mp;
3522 3522          struct seg *seg;
3523 3523          struct seg *brkseg, *stkseg;
3524 3524          uint_t prot;
3525 3525  
3526      -        ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
     3526 +        ASSERT(as != &kas && AS_WRITE_HELD(as));
3527 3527  
3528 3528          /*
3529 3529           * Request an initial buffer size that doesn't waste memory
3530 3530           * if the address space has only a small number of segments.
3531 3531           */
3532 3532          pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
3533 3533  
3534 3534          if ((seg = AS_SEGFIRST(as)) == NULL)
3535 3535                  return (0);
3536 3536  
↓ open down ↓ 39 lines elided ↑ open up ↑
3576 3576  #ifdef _SYSCALL32_IMPL
3577 3577  static int
3578 3578  oprgetmap32(proc_t *p, list_t *iolhead)
3579 3579  {
3580 3580          struct as *as = p->p_as;
3581 3581          ioc_prmap32_t *mp;
3582 3582          struct seg *seg;
3583 3583          struct seg *brkseg, *stkseg;
3584 3584          uint_t prot;
3585 3585  
3586      -        ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
     3586 +        ASSERT(as != &kas && AS_WRITE_HELD(as));
3587 3587  
3588 3588          /*
3589 3589           * Request an initial buffer size that doesn't waste memory
3590 3590           * if the address space has only a small number of segments.
3591 3591           */
3592 3592          pr_iol_initlist(iolhead, sizeof (*mp), avl_numnodes(&as->a_segtree));
3593 3593  
3594 3594          if ((seg = AS_SEGFIRST(as)) == NULL)
3595 3595                  return (0);
3596 3596  
↓ open down ↓ 39 lines elided ↑ open up ↑
3636 3636  
3637 3637  /*
3638 3638   * Return the size of the old /proc page data file.
3639 3639   */
3640 3640  size_t
3641 3641  oprpdsize(struct as *as)
3642 3642  {
3643 3643          struct seg *seg;
3644 3644          size_t size;
3645 3645  
3646      -        ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
     3646 +        ASSERT(as != &kas && AS_WRITE_HELD(as));
3647 3647  
3648 3648          if ((seg = AS_SEGFIRST(as)) == NULL)
3649 3649                  return (0);
3650 3650  
3651 3651          size = sizeof (prpageheader_t);
3652 3652          do {
3653 3653                  caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
3654 3654                  caddr_t saddr, naddr;
3655 3655                  void *tmp = NULL;
3656 3656                  size_t npage;
↓ open down ↓ 9 lines elided ↑ open up ↑
3666 3666          return (size);
3667 3667  }
3668 3668  
3669 3669  #ifdef _SYSCALL32_IMPL
3670 3670  size_t
3671 3671  oprpdsize32(struct as *as)
3672 3672  {
3673 3673          struct seg *seg;
3674 3674          size_t size;
3675 3675  
3676      -        ASSERT(as != &kas && AS_WRITE_HELD(as, &as->a_lock));
     3676 +        ASSERT(as != &kas && AS_WRITE_HELD(as));
3677 3677  
3678 3678          if ((seg = AS_SEGFIRST(as)) == NULL)
3679 3679                  return (0);
3680 3680  
3681 3681          size = sizeof (ioc_prpageheader32_t);
3682 3682          do {
3683 3683                  caddr_t eaddr = seg->s_base + pr_getsegsize(seg, 0);
3684 3684                  caddr_t saddr, naddr;
3685 3685                  void *tmp = NULL;
3686 3686                  size_t npage;
↓ open down ↓ 17 lines elided ↑ open up ↑
3704 3704  oprpdread(struct as *as, uint_t hatid, struct uio *uiop)
3705 3705  {
3706 3706          caddr_t buf;
3707 3707          size_t size;
3708 3708          prpageheader_t *php;
3709 3709          prasmap_t *pmp;
3710 3710          struct seg *seg;
3711 3711          int error;
3712 3712  
3713 3713  again:
3714      -        AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
     3714 +        AS_LOCK_ENTER(as, RW_WRITER);
3715 3715  
3716 3716          if ((seg = AS_SEGFIRST(as)) == NULL) {
3717      -                AS_LOCK_EXIT(as, &as->a_lock);
     3717 +                AS_LOCK_EXIT(as);
3718 3718                  return (0);
3719 3719          }
3720 3720          size = oprpdsize(as);
3721 3721          if (uiop->uio_resid < size) {
3722      -                AS_LOCK_EXIT(as, &as->a_lock);
     3722 +                AS_LOCK_EXIT(as);
3723 3723                  return (E2BIG);
3724 3724          }
3725 3725  
3726 3726          buf = kmem_zalloc(size, KM_SLEEP);
3727 3727          php = (prpageheader_t *)buf;
3728 3728          pmp = (prasmap_t *)(buf + sizeof (prpageheader_t));
3729 3729  
3730 3730          hrt2ts(gethrtime(), &php->pr_tstamp);
3731 3731          php->pr_nmap = 0;
3732 3732          php->pr_npage = 0;
↓ open down ↓ 25 lines elided ↑ open up ↑
3758 3758                           * overrun the buffer whose size we computed based
3759 3759                           * on the initial iteration through the segments.
3760 3760                           * Once we've detected an overflow, we need to clean
3761 3761                           * up the temporary memory allocated in pr_getprot()
3762 3762                           * and retry. If there's a pending signal, we return
3763 3763                           * EINTR so that this thread can be dislodged if
3764 3764                           * a latent bug causes us to spin indefinitely.
3765 3765                           */
3766 3766                          if (next > (uintptr_t)buf + size) {
3767 3767                                  pr_getprot_done(&tmp);
3768      -                                AS_LOCK_EXIT(as, &as->a_lock);
     3768 +                                AS_LOCK_EXIT(as);
3769 3769  
3770 3770                                  kmem_free(buf, size);
3771 3771  
3772 3772                                  if (ISSIG(curthread, JUSTLOOKING))
3773 3773                                          return (EINTR);
3774 3774  
3775 3775                                  goto again;
3776 3776                          }
3777 3777  
3778 3778                          php->pr_nmap++;
↓ open down ↓ 11 lines elided ↑ open up ↑
3790 3790                          if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
3791 3791                                  pmp->pr_mflags |= MA_SHARED;
3792 3792                          pmp->pr_pagesize = PAGESIZE;
3793 3793                          hat_getstat(as, saddr, len, hatid,
3794 3794                              (char *)(pmp + 1), HAT_SYNC_ZERORM);
3795 3795                          pmp = (prasmap_t *)next;
3796 3796                  }
3797 3797                  ASSERT(tmp == NULL);
3798 3798          } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3799 3799  
3800      -        AS_LOCK_EXIT(as, &as->a_lock);
     3800 +        AS_LOCK_EXIT(as);
3801 3801  
3802 3802          ASSERT((uintptr_t)pmp <= (uintptr_t)buf + size);
3803 3803          error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
3804 3804          kmem_free(buf, size);
3805 3805  
3806 3806          return (error);
3807 3807  }
3808 3808  
3809 3809  #ifdef _SYSCALL32_IMPL
3810 3810  int
3811 3811  oprpdread32(struct as *as, uint_t hatid, struct uio *uiop)
3812 3812  {
3813 3813          caddr_t buf;
3814 3814          size_t size;
3815 3815          ioc_prpageheader32_t *php;
3816 3816          ioc_prasmap32_t *pmp;
3817 3817          struct seg *seg;
3818 3818          int error;
3819 3819  
3820 3820  again:
3821      -        AS_LOCK_ENTER(as, &as->a_lock, RW_WRITER);
     3821 +        AS_LOCK_ENTER(as, RW_WRITER);
3822 3822  
3823 3823          if ((seg = AS_SEGFIRST(as)) == NULL) {
3824      -                AS_LOCK_EXIT(as, &as->a_lock);
     3824 +                AS_LOCK_EXIT(as);
3825 3825                  return (0);
3826 3826          }
3827 3827          size = oprpdsize32(as);
3828 3828          if (uiop->uio_resid < size) {
3829      -                AS_LOCK_EXIT(as, &as->a_lock);
     3829 +                AS_LOCK_EXIT(as);
3830 3830                  return (E2BIG);
3831 3831          }
3832 3832  
3833 3833          buf = kmem_zalloc(size, KM_SLEEP);
3834 3834          php = (ioc_prpageheader32_t *)buf;
3835 3835          pmp = (ioc_prasmap32_t *)(buf + sizeof (ioc_prpageheader32_t));
3836 3836  
3837 3837          hrt2ts32(gethrtime(), &php->pr_tstamp);
3838 3838          php->pr_nmap = 0;
3839 3839          php->pr_npage = 0;
↓ open down ↓ 25 lines elided ↑ open up ↑
3865 3865                           * overrun the buffer whose size we computed based
3866 3866                           * on the initial iteration through the segments.
3867 3867                           * Once we've detected an overflow, we need to clean
3868 3868                           * up the temporary memory allocated in pr_getprot()
3869 3869                           * and retry. If there's a pending signal, we return
3870 3870                           * EINTR so that this thread can be dislodged if
3871 3871                           * a latent bug causes us to spin indefinitely.
3872 3872                           */
3873 3873                          if (next > (uintptr_t)buf + size) {
3874 3874                                  pr_getprot_done(&tmp);
3875      -                                AS_LOCK_EXIT(as, &as->a_lock);
     3875 +                                AS_LOCK_EXIT(as);
3876 3876  
3877 3877                                  kmem_free(buf, size);
3878 3878  
3879 3879                                  if (ISSIG(curthread, JUSTLOOKING))
3880 3880                                          return (EINTR);
3881 3881  
3882 3882                                  goto again;
3883 3883                          }
3884 3884  
3885 3885                          php->pr_nmap++;
↓ open down ↓ 11 lines elided ↑ open up ↑
3897 3897                          if (SEGOP_GETTYPE(seg, saddr) & MAP_SHARED)
3898 3898                                  pmp->pr_mflags |= MA_SHARED;
3899 3899                          pmp->pr_pagesize = PAGESIZE;
3900 3900                          hat_getstat(as, saddr, len, hatid,
3901 3901                              (char *)(pmp + 1), HAT_SYNC_ZERORM);
3902 3902                          pmp = (ioc_prasmap32_t *)next;
3903 3903                  }
3904 3904                  ASSERT(tmp == NULL);
3905 3905          } while ((seg = AS_SEGNEXT(as, seg)) != NULL);
3906 3906  
3907      -        AS_LOCK_EXIT(as, &as->a_lock);
     3907 +        AS_LOCK_EXIT(as);
3908 3908  
3909 3909          ASSERT((uintptr_t)pmp == (uintptr_t)buf + size);
3910 3910          error = uiomove(buf, (caddr_t)pmp - buf, UIO_READ, uiop);
3911 3911          kmem_free(buf, size);
3912 3912  
3913 3913          return (error);
3914 3914  }
3915 3915  #endif  /* _SYSCALL32_IMPL */
3916 3916  
3917 3917  /*ARGSUSED*/
↓ open down ↓ 21 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX