[sheepdog] [PATCH 1/2] object cache: introduce background pusher to boost flush performance
MORITA Kazutaka
morita.kazutaka at gmail.com
Sat Jan 26 10:23:03 CET 2013
> +
> +/*
> + * Try to push dirty objects in the background to boost VM flush request such as
> + * fsync().
> + *
> + * This doesn't voliate the flush semantics because the flush request will
> + * still be served synchronously and guaranteed to drain all the dirty objects.
> + */
> +static void do_async_push(struct work *work)
> +{
> + struct push_work *pw = container_of(work, struct push_work, work);
> + struct object_cache *oc = pw->oc;
> + struct object_cache_entry *entry;
> +
> + sd_dprintf("%"PRIx32"\n", oc->vid);
> +next:
> + pthread_rwlock_wrlock(&oc->lock);
> + if (list_empty(&oc->dirty_head)) {
> + pthread_rwlock_unlock(&oc->lock);
> + return;
> + }
> + entry = list_first_entry(&oc->dirty_head, typeof(*entry), dirty_list);
> + uatomic_inc(&entry->refcnt);
> + uatomic_dec(&oc->dirty_count);
> + pthread_rwlock_unlock(&oc->lock);
> +
> + pthread_rwlock_rdlock(&entry->lock);
> +
> + assert(push_cache_object(oc->vid, entry_idx(entry), entry->bmap,
> + !!(entry->idx & CACHE_CREATE_BIT))
> + == SD_RES_SUCCESS);
We must not call functions with side effects inside assert. The code
does not compiled if we specify -NDEBUG.
> /* Push back all the dirty objects to sheep cluster storage */
> -static int object_cache_push(struct object_cache *oc)
> +static int object_cache_sync_push(struct object_cache *oc)
> {
> struct object_cache_entry *entry, *t;
> -
> int ret = SD_RES_SUCCESS;
>
> pthread_rwlock_wrlock(&oc->lock);
> list_for_each_entry_safe(entry, t, &oc->dirty_head, dirty_list) {
> - ret = push_cache_object(oc->vid, entry_idx(entry), entry->bmap,
> - !!(entry->idx & CACHE_CREATE_BIT));
> - if (ret != SD_RES_SUCCESS)
> - goto push_failed;
> + if (uatomic_read(&entry->refcnt) > 0)
> + /* async pusher has been handling it */
> + continue;
> +
> + assert(push_cache_object(oc->vid, entry_idx(entry), entry->bmap,
> + !!(entry->idx & CACHE_CREATE_BIT))
> + == SD_RES_SUCCESS);
Same here.
> diff --git a/sheep/sheep.c b/sheep/sheep.c
> index 61e166c..06ed685 100644
> --- a/sheep/sheep.c
> +++ b/sheep/sheep.c
> @@ -375,7 +375,8 @@ static int init_work_queues(void)
> sys->sockfd_wqueue = init_work_queue("sockfd", true);
> if (is_object_cache_enabled()) {
> sys->reclaim_wqueue = init_work_queue("reclaim", true);
> - if (!sys->reclaim_wqueue)
> + sys->push_wqueue = init_work_queue("push", false);
Shouldn't we use a more descriptive name? We now have many work
queues and it is becoming harder to understand each role.
Thanks,
Kazutaka
More information about the sheepdog
mailing list