X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdt%2Fmdt_hsm_cdt_requests.c;h=71353341dc00a23133523fe44e3b08d110da2a1d;hb=HEAD;hp=a07cb7c174f4aacdd8e739bbb53fa491ad0eaf35;hpb=7251fea8dc3c4d29e30c5a3f763c4c33d35f90a7;p=fs%2Flustre-release.git diff --git a/lustre/mdt/mdt_hsm_cdt_requests.c b/lustre/mdt/mdt_hsm_cdt_requests.c index a07cb7c..e09ab30 100644 --- a/lustre/mdt/mdt_hsm_cdt_requests.c +++ b/lustre/mdt/mdt_hsm_cdt_requests.c @@ -23,7 +23,7 @@ * (C) Copyright 2012 Commissariat a l'energie atomique et aux energies * alternatives * - * Copyright (c) 2014, Intel Corporation. + * Copyright (c) 2014, 2017, Intel Corporation. */ /* * lustre/mdt/mdt_hsm_cdt_requests.c @@ -40,12 +40,14 @@ #include #include #include +#include #include "mdt_internal.h" static unsigned int -cdt_request_cookie_hash(struct cfs_hash *hs, const void *key, unsigned int mask) +cdt_request_cookie_hash(struct cfs_hash *hs, const void *key, + const unsigned int bits) { - return cfs_hash_djb2_hash(key, sizeof(u64), mask); + return cfs_hash_djb2_hash(key, sizeof(u64), bits); } static void *cdt_request_cookie_object(struct hlist_node *hnode) @@ -103,99 +105,59 @@ void dump_requests(char *prefix, struct coordinator *cdt) down_read(&cdt->cdt_request_lock); list_for_each_entry(car, &cdt->cdt_request_list, car_request_list) { CDEBUG(D_HSM, "%s fid="DFID" dfid="DFID - " compound/cookie=%#llx/%#llx" + " cookie=%#llx" " action=%s archive#=%d flags=%#llx" " extent=%#llx-%#llx" " gid=%#llx refcount=%d canceled=%d\n", prefix, PFID(&car->car_hai->hai_fid), PFID(&car->car_hai->hai_dfid), - car->car_compound_id, car->car_hai->hai_cookie, + car->car_hai->hai_cookie, hsm_copytool_action2name(car->car_hai->hai_action), car->car_archive_id, car->car_flags, car->car_hai->hai_extent.offset, car->car_hai->hai_extent.length, car->car_hai->hai_gid, - atomic_read(&car->car_refcount), + kref_read(&car->car_refcount), car->car_canceled); } up_read(&cdt->cdt_request_lock); } -struct req_interval_data { - struct cdt_req_progress *crp; - __u64 done_sz; -}; - -/** - * interval tree cb, used to go through all the tree of extent done +/* Interval tree to track reported progress. + * Intervals stored are non-overlapping and non-adjacent. + * When a new interval is added, all intervals that might overlap + * or be adjacent are first removed, with any extra length added to + * the new interval. */ -static enum interval_iter req_interval_cb(struct interval_node *node, - void *args) -{ - struct req_interval_data *data; - ENTRY; - - data = args; - data->done_sz += node->in_extent.end - node->in_extent.start; - RETURN(INTERVAL_ITER_CONT); -} - -/** - * scan the interval tree associated to a request - * to compute the amount of work done - * \param car [IN] request - * \param done_sz [OUT] will be set to the size of work done - */ -void mdt_cdt_get_work_done(struct cdt_agent_req *car, __u64 *done_sz) -{ - struct req_interval_data rid; - struct cdt_req_progress *crp = &car->car_progress; +struct progress_node { + __u64 pn_offset; + __u64 pn_end; + __u64 pn_subtree_last; + struct rb_node pn_rb; +}; - mutex_lock(&crp->crp_lock); +#define START(node) ((node)->pn_offset) +#define LAST(node) ((node)->pn_end) - rid.crp = crp; - rid.done_sz = 0; - interval_iterate(crp->crp_root, req_interval_cb, &rid); - *done_sz = rid.done_sz; +INTERVAL_TREE_DEFINE(struct progress_node, pn_rb, __u64, pn_subtree_last, + START, LAST, static, progress) - mutex_unlock(&crp->crp_lock); -} +#define progress_first(root) rb_entry_safe(interval_tree_first(root), \ + struct progress_node, pn_rb) -#define NODE_VECTOR_SZ 256 -/** +/* * free the interval tree associated to a request */ static void mdt_cdt_free_request_tree(struct cdt_req_progress *crp) { - struct interval_node *node, *vn; - int i; + struct progress_node *node; ENTRY; - mutex_lock(&crp->crp_lock); - - if (crp->crp_max == 0) - goto out; - - /* remove all nodes from tree */ - for (i = 0 ; i < crp->crp_cnt ; i++) { - vn = crp->crp_node[i / NODE_VECTOR_SZ]; - node = &vn[i % NODE_VECTOR_SZ]; - interval_erase(node, &crp->crp_root); + while ((node = progress_first(&crp->crp_root)) != NULL) { + progress_remove(node, &crp->crp_root); + OBD_FREE_PTR(node); } - /* free all sub vectors */ - for (i = 0 ; i <= crp->crp_max / NODE_VECTOR_SZ ; i++) - OBD_FREE(crp->crp_node[i], - NODE_VECTOR_SZ * sizeof(crp->crp_node[i][0])); - - /* free main vector */ - OBD_FREE(crp->crp_node, - sizeof(crp->crp_node[0]) * - (crp->crp_max / NODE_VECTOR_SZ + 1)); - - crp->crp_cnt = 0; - crp->crp_max = 0; -out: - mutex_unlock(&crp->crp_lock); + EXIT; } @@ -205,66 +167,45 @@ out: static int hsm_update_work(struct cdt_req_progress *crp, const struct hsm_extent *extent) { - int rc, osz, nsz; - struct interval_node **new_vv; - struct interval_node *v, *node; - __u64 end; + struct progress_node *node; + struct progress_node *overlap; + __u64 end; + __u64 total; ENTRY; - end = extent->offset + extent->length; - if (end <= extent->offset) + end = extent->offset + extent->length - 1; + if (end < extent->offset) RETURN(-EINVAL); - mutex_lock(&crp->crp_lock); - /* new node index */ - - if (crp->crp_cnt >= crp->crp_max) { - /* no more room */ - /* allocate a new vector */ - OBD_ALLOC(v, NODE_VECTOR_SZ * sizeof(v[0])); - if (v == NULL) - GOTO(out, rc = -ENOMEM); - - if (crp->crp_max == 0) - osz = 0; - else - osz = sizeof(new_vv[0]) * - (crp->crp_max / NODE_VECTOR_SZ + 1); - - nsz = osz + sizeof(new_vv[0]); - /* increase main vector size */ - OBD_ALLOC(new_vv, nsz); - if (new_vv == NULL) { - OBD_FREE(v, NODE_VECTOR_SZ * sizeof(v[0])); - GOTO(out, rc = -ENOMEM); - } - - if (osz == 0) { - crp->crp_max = NODE_VECTOR_SZ - 1; - } else { - memcpy(new_vv, crp->crp_node, osz); - OBD_FREE(crp->crp_node, osz); - crp->crp_max += NODE_VECTOR_SZ; - } - - crp->crp_node = new_vv; - crp->crp_node[crp->crp_max / NODE_VECTOR_SZ] = v; + OBD_ALLOC_PTR(node); + if (!node) + RETURN(-ENOMEM); + node->pn_offset = extent->offset; + node->pn_end = end; + + spin_lock(&crp->crp_lock); + total = crp->crp_total; + /* Search just before and just after the target interval + * to find intervals that would be adjacent. Remove them + * too and add their extra length to 'node'. + */ + while ((overlap = progress_iter_first(&crp->crp_root, + (node->pn_offset == 0 ? + 0 : node->pn_offset - 1), + (node->pn_end == LUSTRE_EOF ? + LUSTRE_EOF : node->pn_end + 1))) + != NULL) { + node->pn_offset = min(node->pn_offset, overlap->pn_offset); + node->pn_end = max(node->pn_end, overlap->pn_end); + progress_remove(overlap, &crp->crp_root); + total -= overlap->pn_end - overlap->pn_offset + 1; + OBD_FREE_PTR(overlap); } - - v = crp->crp_node[crp->crp_cnt / NODE_VECTOR_SZ]; - node = &v[crp->crp_cnt % NODE_VECTOR_SZ]; - rc = interval_set(node, extent->offset, end); - if (rc) - GOTO(out, rc); - /* try to insert, if entry already exist ignore the new one - * it can happen if ct sends 2 times the same progress */ - if (interval_insert(node, &crp->crp_root) == NULL) - crp->crp_cnt++; - - rc = 0; -out: - mutex_unlock(&crp->crp_lock); - RETURN(rc); + progress_insert(node, &crp->crp_root); + total += node->pn_end - node->pn_offset + 1; + crp->crp_total = total; + spin_unlock(&crp->crp_lock); + RETURN(0); } /** @@ -272,15 +213,15 @@ out: */ static void mdt_cdt_init_request_tree(struct cdt_req_progress *crp) { - mutex_init(&crp->crp_lock); - crp->crp_root = NULL; - crp->crp_cnt = 0; - crp->crp_max = 0; + spin_lock_init(&crp->crp_lock); + crp->crp_root = INTERVAL_TREE_ROOT; + if (0) + /* Silence a warning about unused function */ + progress_iter_next(NULL, 0, 0); } /** Allocate/init an agent request and its sub-structures. * - * \param compound_id [IN] * \param archive_id [IN] * \param flags [IN] * \param uuid [IN] @@ -288,8 +229,8 @@ static void mdt_cdt_init_request_tree(struct cdt_req_progress *crp) * \retval car [OUT] success valid structure * \retval car [OUT] */ -struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id, - __u64 flags, struct obd_uuid *uuid, +struct cdt_agent_req *mdt_cdt_alloc_request(__u32 archive_id, __u64 flags, + struct obd_uuid *uuid, struct hsm_action_item *hai) { struct cdt_agent_req *car; @@ -299,12 +240,11 @@ struct cdt_agent_req *mdt_cdt_alloc_request(__u64 compound_id, __u32 archive_id, if (car == NULL) RETURN(ERR_PTR(-ENOMEM)); - atomic_set(&car->car_refcount, 1); - car->car_compound_id = compound_id; + kref_init(&car->car_refcount); car->car_archive_id = archive_id; car->car_flags = flags; car->car_canceled = 0; - car->car_req_start = cfs_time_current_sec(); + car->car_req_start = ktime_get_real_seconds(); car->car_req_update = car->car_req_start; car->car_uuid = *uuid; OBD_ALLOC(car->car_hai, hai->hai_len); @@ -336,7 +276,15 @@ void mdt_cdt_free_request(struct cdt_agent_req *car) */ void mdt_cdt_get_request(struct cdt_agent_req *car) { - atomic_inc(&car->car_refcount); + kref_get(&car->car_refcount); +} + +static void mdt_cdt_put_request_free(struct kref *kref) +{ + struct cdt_agent_req *car; + + car = container_of(kref, struct cdt_agent_req, car_refcount); + mdt_cdt_free_request(car); } /** @@ -346,9 +294,7 @@ void mdt_cdt_get_request(struct cdt_agent_req *car) */ void mdt_cdt_put_request(struct cdt_agent_req *car) { - LASSERT(atomic_read(&car->car_refcount) > 0); - if (atomic_dec_and_test(&car->car_refcount)) - mdt_cdt_free_request(car); + kref_put(&car->car_refcount, mdt_cdt_put_request_free); } /** @@ -382,6 +328,17 @@ int mdt_cdt_add_request(struct coordinator *cdt, struct cdt_agent_req *car) mdt_hsm_agent_update_statistics(cdt, 0, 0, 1, &car->car_uuid); + switch (car->car_hai->hai_action) { + case HSMA_ARCHIVE: + atomic_inc(&cdt->cdt_archive_count); + break; + case HSMA_RESTORE: + atomic_inc(&cdt->cdt_restore_count); + break; + case HSMA_REMOVE: + atomic_inc(&cdt->cdt_remove_count); + break; + } atomic_inc(&cdt->cdt_request_count); RETURN(0); @@ -427,6 +384,18 @@ int mdt_cdt_remove_request(struct coordinator *cdt, __u64 cookie) list_del(&car->car_request_list); up_write(&cdt->cdt_request_lock); + switch (car->car_hai->hai_action) { + case HSMA_ARCHIVE: + atomic_dec(&cdt->cdt_archive_count); + break; + case HSMA_RESTORE: + atomic_dec(&cdt->cdt_restore_count); + break; + case HSMA_REMOVE: + atomic_dec(&cdt->cdt_remove_count); + break; + } + /* Drop reference from cdt_request_list. */ mdt_cdt_put_request(car); @@ -459,7 +428,7 @@ struct cdt_agent_req *mdt_cdt_update_request(struct coordinator *cdt, if (car == NULL) RETURN(ERR_PTR(-ENOENT)); - car->car_req_update = cfs_time_current_sec(); + car->car_req_update = ktime_get_real_seconds(); /* update data move progress done by copy tool */ if (car->car_hai->hai_action != HSMA_REMOVE && pgs->hpk_errval == 0 && @@ -542,14 +511,12 @@ static int mdt_hsm_active_requests_proc_show(struct seq_file *s, void *v) struct list_head *pos = v; struct cdt_agent_req *car; char buf[12]; - __u64 data_moved; ENTRY; if (pos == SEQ_START_TOKEN) RETURN(0); car = list_entry(pos, struct cdt_agent_req, car_request_list); - mdt_cdt_get_work_done(car, &data_moved); seq_printf(s, "fid="DFID" dfid="DFID " compound/cookie=%#llx/%#llx" @@ -558,7 +525,7 @@ static int mdt_hsm_active_requests_proc_show(struct seq_file *s, void *v) " data=[%s] canceled=%d uuid=%s done=%llu\n", PFID(&car->car_hai->hai_fid), PFID(&car->car_hai->hai_dfid), - car->car_compound_id, car->car_hai->hai_cookie, + 0ULL /* compound_id */, car->car_hai->hai_cookie, hsm_copytool_action2name(car->car_hai->hai_action), car->car_archive_id, car->car_flags, car->car_hai->hai_extent.offset, @@ -566,7 +533,7 @@ static int mdt_hsm_active_requests_proc_show(struct seq_file *s, void *v) car->car_hai->hai_gid, hai_dump_data_field(car->car_hai, buf, sizeof(buf)), car->car_canceled, obd_uuid2str(&car->car_uuid), - data_moved); + car->car_progress.crp_total); RETURN(0); } @@ -596,8 +563,8 @@ static const struct seq_operations mdt_hsm_active_requests_proc_ops = { * public function called at open of /proc file to get * list of agents */ -static int lprocfs_open_hsm_active_requests(struct inode *inode, - struct file *file) +static int ldebugfs_open_hsm_active_requests(struct inode *inode, + struct file *file) { struct seq_file *s; int rc; @@ -608,7 +575,7 @@ static int lprocfs_open_hsm_active_requests(struct inode *inode, RETURN(rc); } s = file->private_data; - s->private = PDE_DATA(inode); + s->private = inode->i_private; RETURN(rc); } @@ -616,9 +583,9 @@ static int lprocfs_open_hsm_active_requests(struct inode *inode, /* methods to access hsm request list */ const struct file_operations mdt_hsm_active_requests_fops = { .owner = THIS_MODULE, - .open = lprocfs_open_hsm_active_requests, + .open = ldebugfs_open_hsm_active_requests, .read = seq_read, .llseek = seq_lseek, - .release = lprocfs_seq_release, + .release = seq_release, };