From: Yu Kuai <yukuai3@xxxxxxxxxx> IO fast path will set bits to dirty, and those dirty bits will be cleared by daemon after IO is done. llbitmap_barrier is used to synchronize between IO path and daemon; IO path: 1) try to grab a reference, if succeed, set expire time after 5s and return; 2) if failed to grab a reference, wait for daemon to finish clearing dirty bits; Daemon(Daemon will be waken up every daemon_sleep seconds): For each page: 1) check if page expired, if not skip this page; for expired page: 2) suspend the page and wait for inflight write IO to be done; 3) change dirty page to clean; 4) resume the page; Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx> --- drivers/md/md-llbitmap.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c index f782f092ab5d..4d5f9a139a25 100644 --- a/drivers/md/md-llbitmap.c +++ b/drivers/md/md-llbitmap.c @@ -651,4 +651,42 @@ static enum llbitmap_state llbitmap_state_machine(struct llbitmap *llbitmap, return state; } +static void llbitmap_raise_barrier(struct llbitmap *llbitmap, int page_idx) +{ + struct llbitmap_page_ctl *pctl = llbitmap->pctl[page_idx]; + +retry: + if (likely(percpu_ref_tryget_live(&pctl->active))) { + WRITE_ONCE(pctl->expire, jiffies + BARRIER_IDLE * HZ); + return; + } + + wait_event(pctl->wait, !percpu_ref_is_dying(&pctl->active)); + goto retry; +} + +static void llbitmap_release_barrier(struct llbitmap *llbitmap, int page_idx) +{ + struct llbitmap_page_ctl *pctl = llbitmap->pctl[page_idx]; + + percpu_ref_put(&pctl->active); +} + +static void llbitmap_suspend(struct llbitmap *llbitmap, int page_idx) +{ + struct llbitmap_page_ctl *pctl = llbitmap->pctl[page_idx]; + + percpu_ref_kill(&pctl->active); + wait_event(pctl->wait, percpu_ref_is_zero(&pctl->active)); +} + +static void llbitmap_resume(struct llbitmap *llbitmap, int page_idx) +{ + struct llbitmap_page_ctl *pctl = llbitmap->pctl[page_idx]; + + pctl->expire = LONG_MAX; + percpu_ref_resurrect(&pctl->active); + wake_up(&pctl->wait); +} + #endif /* CONFIG_MD_LLBITMAP */ -- 2.39.2