Whamcloud - gitweb
LU-15245 mdc: GET(X)ATTR to READPAGE portal 93/45593/1
authorPatrick Farrell <pfarrell@whamcloud.com>
Wed, 17 Nov 2021 20:01:51 +0000 (15:01 -0500)
committerPatrick Farrell <pfarrell@whamcloud.com>
Wed, 17 Nov 2021 20:01:51 +0000 (15:01 -0500)
Send the MDS_GETATTR and MDS_GETXATTR RPCs to the
MDS_READPAGE_PORTAL instead of the default portal to avoid
deadlocks with other MDS_REINT RPCs that may block all of
the MDS service threads on that portal.

This deadlock occurs with MDS_GETXATTR when selinux is
enabled, because getxattr becomes part of lookup, so it
takes a reference on a lock used for lookup.  However, all
of the MDS service threads on the default portal can be
consumed by threads waiting for that lock, resulting in
a deadlock when the getxattr can't be processed.

Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Signed-off-by: Patrick Farrell <pfarrell@whamcloud.com>
Change-Id: I4fbae266022ee9fa38f3196acb1443df5056fe5e

lustre/llite/rw26.c
lustre/llite/vvp_page.c
lustre/mdc/mdc_request.c

index e959e6b..d2b31aa 100644 (file)
@@ -118,21 +118,23 @@ static int ll_releasepage(struct page *vmpage, RELEASEPAGE_ARG_TYPE gfp_mask)
        struct address_space    *mapping;
        int result = 0;
 
+       ENTRY;
+
        LASSERT(PageLocked(vmpage));
        if (PageWriteback(vmpage) || PageDirty(vmpage))
-               return 0;
+               RETURN(0);
 
        mapping = vmpage->mapping;
        if (mapping == NULL)
-               return 1;
+               RETURN(1);
 
        obj = ll_i2info(mapping->host)->lli_clob;
        if (obj == NULL)
-               return 1;
+               RETURN(1);
 
        page = cl_vmpage_page(vmpage, obj);
        if (page == NULL)
-               return 1;
+               RETURN(1);
 
        env = cl_env_percpu_get();
        LASSERT(!IS_ERR(env));
@@ -159,7 +161,7 @@ static int ll_releasepage(struct page *vmpage, RELEASEPAGE_ARG_TYPE gfp_mask)
        cl_page_put(env, page);
 
        cl_env_percpu_put(env);
-       return result;
+       RETURN(result);
 }
 
 #if defined(HAVE_DIRECTIO_ITER) || defined(HAVE_IOV_ITER_RW) || \
index 3a3bc9e..5157a73 100644 (file)
@@ -152,6 +152,8 @@ static void vvp_page_discard(const struct lu_env *env,
        struct page     *vmpage = cl2vm_page(slice);
        struct vvp_page *vpg    = cl2vvp_page(slice);
 
+       ENTRY;
+
        LASSERT(vmpage != NULL);
        LASSERT(PageLocked(vmpage));
 
@@ -159,6 +161,8 @@ static void vvp_page_discard(const struct lu_env *env,
                ll_ra_stats_inc(vmpage->mapping->host, RA_STAT_DISCARDED);
 
        generic_error_remove_page(vmpage->mapping, vmpage);
+
+       EXIT;
 }
 
 static void vvp_page_delete(const struct lu_env *env,
@@ -168,10 +172,11 @@ static void vvp_page_delete(const struct lu_env *env,
        struct cl_page   *page   = slice->cpl_page;
        int refc;
 
+       ENTRY;
+
        LASSERT(PageLocked(vmpage));
        LASSERT((struct cl_page *)vmpage->private == page);
 
-
        /* Drop the reference count held in vvp_page_init */
        refc = atomic_dec_return(&page->cp_ref);
        LASSERTF(refc >= 1, "page = %p, refc = %d\n", page, refc);
@@ -188,6 +193,8 @@ static void vvp_page_delete(const struct lu_env *env,
         * Reference from vmpage to cl_page is removed, but the reference back
         * is still here. It is removed later in vvp_page_fini().
         */
+
+       EXIT;
 }
 
 static void vvp_page_export(const struct lu_env *env,
index 112a834..005ba77 100644 (file)
@@ -229,6 +229,11 @@ static int mdc_getattr(struct obd_export *exp, struct md_op_data *op_data,
                 RETURN(rc);
         }
 
+       /* Avoid deadlock with modifying RPCs on MDS_REQUEST_PORTAL 
+        * See LU-15245
+        */
+       req->rq_request_portal = MDS_READPAGE_PORTAL;
+
 again:
        mdc_pack_body(&req->rq_pill, &op_data->op_fid1, op_data->op_valid,
                      op_data->op_mode, -1, 0);
@@ -405,6 +410,10 @@ static int mdc_xattr_common(struct obd_export *exp,const struct req_format *fmt,
        } else {
                mdc_pack_body(&req->rq_pill, fid, valid, output_size,
                              suppgid, flags);
+               /* Avoid deadlock with modifying RPCs on MDS_REQUEST_PORTAL 
+                * See LU-15245
+                */
+               req->rq_request_portal = MDS_READPAGE_PORTAL;
        }
 
         if (xattr_name) {