Messages in this thread Patch in this message |  | | From | Yu Kuai <> | | Subject | [PATCH 17/23] md/md-llbitmap: implement APIs for page level dirty bits synchronization | | Date | Sat, 24 May 2025 14:13:14 +0800 |
| |
From: Yu Kuai <yukuai3@huawei.com>
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@huawei.com> --- 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
|  |