From: Mike Snitzer <snitzer@redhat.com>
To: Mikulas Patocka <mpatocka@redhat.com>
Cc: Mike Snitzer <msnitzer@redhat.com>,
jiyong@google.com, kernel-team@android.com,
Heinz Mauelshagen <heinzm@redhat.com>,
dariofreni@google.com, dm-devel@redhat.com, maco@google.com,
Martijn Coenen <maco@android.com>,
Alasdair G Kergon <agk@redhat.com>
Subject: Re: [PATCH v2 5/5] dm-bufio: introduce a global cache replacement
Date: Fri, 13 Sep 2019 12:00:06 -0400 [thread overview]
Message-ID: <20190913160006.GA59158@lobo> (raw)
In-Reply-To: <alpine.LRH.2.02.1909121206130.31437@file01.intranet.prod.int.rdu2.redhat.com>
On Thu, Sep 12 2019 at 12:07P -0400,
Mikulas Patocka <mpatocka@redhat.com> wrote:
>
>
> On Thu, 12 Sep 2019, Heinz Mauelshagen wrote:
>
> > Mikulas,
> >
> > please use list_move instead of list_del/list_add pairs.
> >
> > Heinz
>
> OK. Here I resend it.
>
>
>
> From: Mikulas Patocka <mpatocka@redhat.com>
>
> This patch introduces a global cache replacement (instead of per-client
> cleanup).
>
> If one bufio client uses the cache heavily and another client is not using
> it, we want to let the first client use most of the cache. The old
> algorithm would partition the cache equally betwen the clients and that is
> inoptimal.
>
> For cache replacement, we use the clock algorithm because it doesn't
> require taking any lock when the buffer is accessed.
>
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
I'd like to fold in this cleanup if you're OK with it.
Rather use a main control structure for the loop rather than gotos.
You OK with this?
diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c
index 8c6edec8a838..2d519c223562 100644
--- a/drivers/md/dm-bufio.c
+++ b/drivers/md/dm-bufio.c
@@ -230,7 +230,6 @@ static LIST_HEAD(dm_bufio_all_clients);
*/
static DEFINE_MUTEX(dm_bufio_clients_lock);
-
static struct workqueue_struct *dm_bufio_wq;
static struct delayed_work dm_bufio_cleanup_old_work;
static struct work_struct dm_bufio_replacement_work;
@@ -1827,62 +1826,60 @@ static void do_global_cleanup(struct work_struct *w)
struct dm_bufio_client *current_client;
struct dm_buffer *b;
unsigned spinlock_hold_count;
- unsigned long threshold = dm_bufio_cache_size - dm_bufio_cache_size / DM_BUFIO_LOW_WATERMARK_RATIO;
+ unsigned long threshold = dm_bufio_cache_size -
+ dm_bufio_cache_size / DM_BUFIO_LOW_WATERMARK_RATIO;
unsigned long loops = global_num * 2;
mutex_lock(&dm_bufio_clients_lock);
-reacquire_spinlock:
- cond_resched();
+ while (1) {
+ cond_resched();
- spin_lock(&global_spinlock);
- if (unlikely(dm_bufio_current_allocated <= threshold))
- goto exit;
+ spin_lock(&global_spinlock);
+ if (unlikely(dm_bufio_current_allocated <= threshold))
+ break;
- spinlock_hold_count = 0;
+ spinlock_hold_count = 0;
get_next:
- if (!loops--)
- goto exit;
- if (unlikely(list_empty(&global_queue)))
- goto exit;
- b = list_entry(global_queue.prev, struct dm_buffer, global_list);
-
- if (b->accessed) {
- b->accessed = 0;
- list_move(&b->global_list, &global_queue);
- if (likely(++spinlock_hold_count < 16)) {
- goto get_next;
- }
- spin_unlock(&global_spinlock);
- goto reacquire_spinlock;
- }
-
- current_client = b->c;
- if (unlikely(current_client != locked_client)) {
- if (locked_client)
- dm_bufio_unlock(locked_client);
+ if (!loops--)
+ break;
+ if (unlikely(list_empty(&global_queue)))
+ break;
+ b = list_entry(global_queue.prev, struct dm_buffer, global_list);
- if (!dm_bufio_trylock(current_client)) {
+ if (b->accessed) {
+ b->accessed = 0;
+ list_move(&b->global_list, &global_queue);
+ if (likely(++spinlock_hold_count < 16))
+ goto get_next;
spin_unlock(&global_spinlock);
- dm_bufio_lock(current_client);
- locked_client = current_client;
- goto reacquire_spinlock;
+ continue;
}
- locked_client = current_client;
- }
+ current_client = b->c;
+ if (unlikely(current_client != locked_client)) {
+ if (locked_client)
+ dm_bufio_unlock(locked_client);
- spin_unlock(&global_spinlock);
+ if (!dm_bufio_trylock(current_client)) {
+ spin_unlock(&global_spinlock);
+ dm_bufio_lock(current_client);
+ locked_client = current_client;
+ continue;
+ }
+
+ locked_client = current_client;
+ }
- if (unlikely(!__try_evict_buffer(b, GFP_KERNEL))) {
- spin_lock(&global_spinlock);
- list_move(&b->global_list, &global_queue);
spin_unlock(&global_spinlock);
- }
- goto reacquire_spinlock;
+ if (unlikely(!__try_evict_buffer(b, GFP_KERNEL))) {
+ spin_lock(&global_spinlock);
+ list_move(&b->global_list, &global_queue);
+ spin_unlock(&global_spinlock);
+ }
+ }
-exit:
spin_unlock(&global_spinlock);
if (locked_client)
next prev parent reply other threads:[~2019-09-13 16:00 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-12 8:44 [PATCH 5/5] dm-bufio: introduce a global cache replacement Mikulas Patocka
2019-09-12 11:59 ` Heinz Mauelshagen
2019-09-12 16:07 ` [PATCH v2 " Mikulas Patocka
2019-09-13 16:00 ` Mike Snitzer [this message]
2019-09-13 19:00 ` Mikulas Patocka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190913160006.GA59158@lobo \
--to=snitzer@redhat.com \
--cc=agk@redhat.com \
--cc=dariofreni@google.com \
--cc=dm-devel@redhat.com \
--cc=heinzm@redhat.com \
--cc=jiyong@google.com \
--cc=kernel-team@android.com \
--cc=maco@android.com \
--cc=maco@google.com \
--cc=mpatocka@redhat.com \
--cc=msnitzer@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.