mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
gfs2: Fix "Make glock lru list scanning safer"
Commit 228804a35c
tried to add a refcount check to
gfs2_scan_glock_lru() to make sure that glocks that are still referenced
cannot be freed. It failed to account for the bias state_change() adds
to the refcount for held glocks, so held glocks are no longer removed
from the glock cache, which can lead to out-of-memory problems. Fix
that. (The inodes those glocks are associated with do get shrunk and do
get pushed out of memory.)
In addition, use the same eligibility check in gfs2_scan_glock_lru() and
gfs2_dispose_glock_lru().
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
This commit is contained in:
parent
c9a0a4b028
commit
acf1f42faf
@ -1987,6 +1987,14 @@ static int glock_cmp(void *priv, const struct list_head *a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool can_free_glock(struct gfs2_glock *gl)
|
||||
{
|
||||
bool held = gl->gl_state != LM_ST_UNLOCKED;
|
||||
|
||||
return !test_bit(GLF_LOCK, &gl->gl_flags) &&
|
||||
gl->gl_lockref.count == held;
|
||||
}
|
||||
|
||||
/**
|
||||
* gfs2_dispose_glock_lru - Demote a list of glocks
|
||||
* @list: The list to dispose of
|
||||
@ -2020,7 +2028,7 @@ add_back_to_lru:
|
||||
atomic_inc(&lru_count);
|
||||
continue;
|
||||
}
|
||||
if (test_bit(GLF_LOCK, &gl->gl_flags)) {
|
||||
if (!can_free_glock(gl)) {
|
||||
spin_unlock(&gl->gl_lockref.lock);
|
||||
goto add_back_to_lru;
|
||||
}
|
||||
@ -2052,16 +2060,10 @@ static long gfs2_scan_glock_lru(int nr)
|
||||
list_for_each_entry_safe(gl, next, &lru_list, gl_lru) {
|
||||
if (nr-- <= 0)
|
||||
break;
|
||||
/* Test for being demotable */
|
||||
if (!test_bit(GLF_LOCK, &gl->gl_flags)) {
|
||||
if (!spin_trylock(&gl->gl_lockref.lock))
|
||||
continue;
|
||||
if (!gl->gl_lockref.count) {
|
||||
list_move(&gl->gl_lru, &dispose);
|
||||
atomic_dec(&lru_count);
|
||||
freed++;
|
||||
}
|
||||
spin_unlock(&gl->gl_lockref.lock);
|
||||
if (can_free_glock(gl)) {
|
||||
list_move(&gl->gl_lru, &dispose);
|
||||
atomic_dec(&lru_count);
|
||||
freed++;
|
||||
}
|
||||
}
|
||||
if (!list_empty(&dispose))
|
||||
|
Loading…
Reference in New Issue
Block a user