Author: kib
Date: Sun May  5 11:04:01 2019
New Revision: 347148
URL: https://svnweb.freebsd.org/changeset/base/347148

Log:
  imgact_elf: do not relock the text vnode if possible.
  
  We unlock the vnode around malloc(M_WAITOK), to make it possible for
  pagedaemon to flush vnode pages for us.  Instead of doing it
  unconditionally, first try M_NOWAIT allocation, which typically
  succeed.  Only on failure, unlock the vnode and retry with M_WAITOK.
  
  Reviewed by:  markj, trasz
  Tested by:    mjg, pho
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week
  Differential revision:        https://reviews.freebsd.org/D19923

Modified:
  head/sys/kern/imgact_elf.c

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c  Sun May  5 10:57:27 2019        (r347147)
+++ head/sys/kern/imgact_elf.c  Sun May  5 11:04:01 2019        (r347148)
@@ -957,9 +957,12 @@ __elfN(get_interp)(struct image_params *imgp, const El
        interp_name_len = phdr->p_filesz;
        if (phdr->p_offset > PAGE_SIZE ||
            interp_name_len > PAGE_SIZE - phdr->p_offset) {
-               VOP_UNLOCK(imgp->vp, 0);
-               interp = malloc(interp_name_len + 1, M_TEMP, M_WAITOK);
-               vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+               interp = malloc(interp_name_len + 1, M_TEMP, M_NOWAIT);
+               if (interp == NULL) {
+                       VOP_UNLOCK(imgp->vp, 0);
+                       interp = malloc(interp_name_len + 1, M_TEMP, M_WAITOK);
+                       vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+               }
                error = vn_rdwr(UIO_READ, imgp->vp, interp,
                    interp_name_len, phdr->p_offset,
                    UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
@@ -1278,7 +1281,12 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
        /*
         * Construct auxargs table (used by the fixup routine)
         */
-       elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
+       elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_NOWAIT);
+       if (elf_auxargs == NULL) {
+               VOP_UNLOCK(imgp->vp, 0);
+               elf_auxargs = malloc(sizeof(Elf_Auxargs), M_TEMP, M_WAITOK);
+               vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+       }
        elf_auxargs->execfd = -1;
        elf_auxargs->phdr = proghdr + et_dyn_addr;
        elf_auxargs->phent = hdr->e_phentsize;
@@ -2558,9 +2566,12 @@ __elfN(parse_notes)(struct image_params *imgp, Elf_Not
        ASSERT_VOP_LOCKED(imgp->vp, "parse_notes");
        if (pnote->p_offset > PAGE_SIZE ||
            pnote->p_filesz > PAGE_SIZE - pnote->p_offset) {
-               VOP_UNLOCK(imgp->vp, 0);
-               buf = malloc(pnote->p_filesz, M_TEMP, M_WAITOK);
-               vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+               buf = malloc(pnote->p_filesz, M_TEMP, M_NOWAIT);
+               if (buf == NULL) {
+                       VOP_UNLOCK(imgp->vp, 0);
+                       buf = malloc(pnote->p_filesz, M_TEMP, M_WAITOK);
+                       vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
+               }
                error = vn_rdwr(UIO_READ, imgp->vp, buf, pnote->p_filesz,
                    pnote->p_offset, UIO_SYSSPACE, IO_NODELOCKED,
                    curthread->td_ucred, NOCRED, NULL, curthread);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to