From mboxrd@z Thu Jan 1 00:00:00 1970 From: Minfei Huang Subject: [PATCH] fs/buffer: simplify the code flow of LRU management algorithm Date: Thu, 10 Sep 2015 16:09:39 +0800 Message-ID: <1441872579-31595-1-git-send-email-mhuang@redhat.com> Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, mhuang@redhat.com, Minfei Huang To: viro@zeniv.linux.org.uk Return-path: Received: from mx1.redhat.com ([209.132.183.28]:42894 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751484AbbIJIEe (ORCPT ); Thu, 10 Sep 2015 04:04:34 -0400 Sender: linux-fsdevel-owner@vger.kernel.org List-ID: From: Minfei Huang There is a buffer_head lru list cache in local cpu to accelerate the speed. The LRU management algorithm is simple enough in bh_lru_install(). There are three situtaions we should deal with. 1) All/part of the lru cache is NULL. 2) The new buffer_head hitts the lru cache. 3) The new buffer_head does hit the lru cache. We put the new buffer_head at the head of lru cache, then copy the buffer_head from the original lru cache, and drop the spare. Signed-off-by: Minfei Huang --- fs/buffer.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 1cf7a53..2139574 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1287,8 +1287,6 @@ static inline void check_irqs_on(void) */ static void bh_lru_install(struct buffer_head *bh) { - struct buffer_head *evictee = NULL; - check_irqs_on(); bh_lru_lock(); if (__this_cpu_read(bh_lrus.bhs[0]) != bh) { @@ -1302,25 +1300,35 @@ static void bh_lru_install(struct buffer_head *bh) struct buffer_head *bh2 = __this_cpu_read(bh_lrus.bhs[in]); - if (bh2 == bh) { + if (bh2 == NULL) { + /* Rest value in bh_lrus.bhs always is NULL */ + break; + } else if (bh2 == bh) { __brelse(bh2); } else { - if (out >= BH_LRU_SIZE) { - BUG_ON(evictee != NULL); - evictee = bh2; + if (out == BH_LRU_SIZE) { + /* + * this condition will be happened, + * only if none of entry in + * bh_lrus.bhs hits the new bh, + * so the last bh should be released. + */ + BUG_ON(in != BH_LRU_SIZE - 1); + __brelse(bh2); + break; } else { bhs[out++] = bh2; } } } - while (out < BH_LRU_SIZE) - bhs[out++] = NULL; - memcpy(this_cpu_ptr(&bh_lrus.bhs), bhs, sizeof(bhs)); + /* + * it is fine that the value out may be smaller than + * BH_LRU_SIZE. The rest of the value in bh_lrus.bhs is NULL. + */ + memcpy(this_cpu_ptr(&bh_lrus.bhs), bhs, + sizeof(struct buffer_head *) * out); } bh_lru_unlock(); - - if (evictee) - __brelse(evictee); } /* -- 2.1.0