cache: mark climb_mount as __noinline

This commit is contained in:
Mateusz Guzik 2020-08-01 06:34:18 +00:00
parent 85cf316172
commit 5a3944334c

View File

@ -3448,7 +3448,7 @@ cache_fplookup_mp_supported(struct mount *mp)
* By the end of successful walk we are guaranteed the reached state was
* indeed present at least at some point which matches the regular lookup.
*/
static int
static int __noinline
cache_fplookup_climb_mount(struct cache_fpl *fpl)
{
struct mount *mp, *prev_mp;
@ -3457,9 +3457,8 @@ cache_fplookup_climb_mount(struct cache_fpl *fpl)
vp = fpl->tvp;
vp_seqc = fpl->tvp_seqc;
if (vp->v_type != VDIR)
return (0);
VNPASS(vp->v_type == VDIR || vp->v_type == VBAD, vp);
mp = atomic_load_ptr(&vp->v_mountedhere);
if (mp == NULL)
return (0);
@ -3503,6 +3502,26 @@ cache_fplookup_climb_mount(struct cache_fpl *fpl)
return (0);
}
static bool
cache_fplookup_need_climb_mount(struct cache_fpl *fpl)
{
struct mount *mp;
struct vnode *vp;
vp = fpl->tvp;
/*
* Hack: while this is a union, the pointer tends to be NULL so save on
* a branch.
*/
mp = atomic_load_ptr(&vp->v_mountedhere);
if (mp == NULL)
return (false);
if (vp->v_type == VDIR)
return (true);
return (false);
}
/*
* Parse the path.
*
@ -3689,9 +3708,11 @@ cache_fplookup_impl(struct vnode *dvp, struct cache_fpl *fpl)
VNPASS(!seqc_in_modify(fpl->tvp_seqc), fpl->tvp);
error = cache_fplookup_climb_mount(fpl);
if (__predict_false(error != 0)) {
break;
if (cache_fplookup_need_climb_mount(fpl)) {
error = cache_fplookup_climb_mount(fpl);
if (__predict_false(error != 0)) {
break;
}
}
VNPASS(!seqc_in_modify(fpl->tvp_seqc), fpl->tvp);