[Crash-utility] [PATCH v2 5/6] Add do_maple_tree support for maple tree
Tao Liu
ltao at redhat.com
Tue Dec 6 09:14:19 UTC 2022
On Thu, Nov 3, 2022 at 10:18 AM lijiang <lijiang at redhat.com> wrote:
>
> On Tue, Oct 25, 2022 at 8:39 PM <crash-utility-request at redhat.com> wrote:
> > Date: Tue, 25 Oct 2022 20:38:24 +0800
> > From: Tao Liu <ltao at redhat.com>
> > To: crash-utility at redhat.com
> > Subject: [Crash-utility] [PATCH v2 5/6] Add do_maple_tree support for
> > maple tree
> > Message-ID: <20221025123825.36421-6-ltao at redhat.com>
> > Content-Type: text/plain; charset="US-ASCII"; x-default=true
> >
> > do_maple_tree() is similar to do_radix_tree() and do_xarray(), which
> > takes the same do_maple_tree_traverse entry as tree cmd. Currently
> > do_maple_tree() is not called by any other functions, we reserve it
> > for future use.
> >
> > Signed-off-by: Tao Liu <ltao at redhat.com>
> > ---
> > defs.h | 6 +++
> > maple_tree.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 155 insertions(+)
> >
> > diff --git a/defs.h b/defs.h
> > index 3f2453e..827e561 100644
> > --- a/defs.h
> > +++ b/defs.h
> > @@ -5581,6 +5581,12 @@ int cleanup_memory_driver(void);
> >
> > void maple_init(void);
> > int do_mptree(struct tree_data *);
> > +ulong do_maple_tree(ulong, int, struct list_pair *);
> > +#define MAPLE_TREE_COUNT (1)
> > +#define MAPLE_TREE_SEARCH (2)
> > +#define MAPLE_TREE_DUMP (3)
> > +#define MAPLE_TREE_GATHER (4)
> > +#define MAPLE_TREE_DUMP_CB (5)
> >
> > /*
> > * help.c
> > diff --git a/maple_tree.c b/maple_tree.c
> > index 33903cb..e8a287a 100644
> > --- a/maple_tree.c
> > +++ b/maple_tree.c
> > @@ -805,6 +805,13 @@ struct cmd_tree_info {
> > struct tree_data *td;
> > } cmd_tree_info;
> >
> > +struct maple_tree_ops {
> > + void (*entry)(ulong node, ulong slot, const char *path,
> > + ulong index, void *private);
> > + uint radix;
> > + void *private;
> > +} maple_tree_ops;
> > +
> > static const char spaces[] = " ";
> >
> > static void do_mt_range64(const struct maple_tree *, void *,
> > @@ -1028,6 +1035,10 @@ static void do_mt_entry(void *entry, unsigned long min, unsigned long max,
> > int print_radix = 0, i;
> > static struct req_entry **e = NULL;
> >
> > + if (maple_tree_ops.entry)
> > + maple_tree_ops.entry((ulong)entry, (ulong)entry, path, max,
> > + maple_tree_ops.private);
> > +
> > if (!cmd_tree_info.td)
> > return;
> >
> > @@ -1162,12 +1173,150 @@ int do_mptree(struct tree_data *td)
> > int is_root = !(td->flags & TREE_NODE_POINTER);
> >
> > memset(&cmd_tree_info, 0, sizeof(cmd_tree_info));
> > + memset(&maple_tree_ops, 0, sizeof(maple_tree_ops));
>
> See comments below.
>
> > cmd_tree_info.td = td;
> > do_maple_tree_traverse(td->start, is_root);
> >
> > return 0;
> > }
> >
> > +/*************For do_maple_tree*****************/
> > +static void do_maple_tree_count(ulong node, ulong slot, const char *path,
> > + ulong index, void *private)
> > +{
> > + struct do_maple_tree_info *info = private;
> > + info->count++;
> > +}
> > +
> > +static void do_maple_tree_search(ulong node, ulong slot, const char *path,
> > + ulong index, void *private)
> > +{
> > + struct do_maple_tree_info *info = private;
> > + struct list_pair *rtp = info->data;
> > +
> > + if (rtp->index == index) {
> > + rtp->value = (void *)slot;
> > + info->count = 1;
> > + }
> > +}
> > +
> > +static void do_maple_tree_dump(ulong node, ulong slot, const char *path,
> > + ulong index, void *private)
> > +{
> > + struct do_maple_tree_info *info = private;
> > + fprintf(fp, "[%lu] %lx\n", index, slot);
> > + info->count++;
> > +}
> > +
> > +static void do_maple_tree_gather(ulong node, ulong slot, const char *path,
> > + ulong index, void *private)
> > +{
> > + struct do_maple_tree_info *info = private;
> > + struct list_pair *rtp = info->data;
> > +
> > + if (info->maxcount) {
> > + rtp[info->count].index = index;
> > + rtp[info->count].value = (void *)slot;
> > +
> > + info->count++;
> > + info->maxcount--;
> > + }
> > +}
> > +
> > +static void do_maple_tree_dump_cb(ulong node, ulong slot, const char *path,
> > + ulong index, void *private)
> > +{
> > + struct do_maple_tree_info *info = private;
> > + struct list_pair *rtp = info->data;
> > + int (*cb)(ulong) = rtp->value;
> > +
> > + /* Caller defined operation */
> > + if (!cb(slot)) {
> > + error(FATAL, "do_maple_tree: callback "
> > + "operation failed: entry: %ld item: %lx\n",
> > + info->count, slot);
> > + }
> > + info->count++;
> > +}
> > +
> > +/*
> > + * do_maple_tree argument usage:
> > + *
> > + * root: Address of a maple_tree_root structure
> > + *
> > + * flag: MAPLE_TREE_COUNT - Return the number of entries in the tree.
> > + * MAPLE_TREE_SEARCH - Search for an entry at rtp->index; if found,
> > + * store the entry in rtp->value and return a count of 1; otherwise
> > + * return a count of 0.
> > + * MAPLE_TREE_DUMP - Dump all existing index/value pairs.
> > + * MAPLE_TREE_GATHER - Store all existing index/value pairs in the
> > + * passed-in array of list_pair structs starting at rtp,
> > + * returning the count of entries stored; the caller can/should
> > + * limit the number of returned entries by putting the array size
> > + * (max count) in the rtp->index field of the first structure
> > + * in the passed-in array.
> > + * MAPLE_TREE_DUMP_CB - Similar with MAPLE_TREE_DUMP, but for each
> > + * maple tree entry, a user defined callback at rtp->value will
> > + * be invoked.
> > + *
> > + * rtp: Unused by MAPLE_TREE_COUNT and MAPLE_TREE_DUMP.
> ^^^
> > + * A pointer to a list_pair structure for MAPLE_TREE_SEARCH.
> > + * A pointer to an array of list_pair structures for
> > + * MAPLE_TREE_GATHER; the dimension (max count) of the array may
> > + * be stored in the index field of the first structure to avoid
> > + * any chance of an overrun.
> > + * For MAPLE_TREE_DUMP_CB, the rtp->value must be initialized as a
> > + * callback function. The callback prototype must be: int (*)(ulong);
> > + */
> > +ulong
> > +do_maple_tree(ulong root, int flag, struct list_pair *rtp)
>
> The parameter name "rtp" looks a bit weird, could you please replace
> the "rtp" with the "lp" and update the above comment?
Fixed in v3...
>
> > +{
> > + struct do_maple_tree_info info = {
> > + .count = 0,
> > + .data = rtp,
> Ditto.
>
> > + };
> > +
> > + memset(&maple_tree_ops, 0, sizeof(maple_tree_ops));
> > + memset(&cmd_tree_info, 0, sizeof(cmd_tree_info));
> > + maple_tree_ops.private = &info;
>
> Think about it again. It could be good to use a local variable and
> eventually pass the ops parameter to do_maple_tree_traverse(). Just
> like:
>
Yes, good suggestion, I have reimplemented the code, it has been made
local variables instead of global.
> //filesys.c
> struct do_radix_tree_info info = {
> .count = 0,
> .data = rtp,
> };
> struct radix_tree_ops ops = {
> .radix = 16,
> .private = &info,
> };
>
>
> > +
> > + switch (flag)
> > + {
> > + case MAPLE_TREE_COUNT:
> > + maple_tree_ops.entry = do_maple_tree_count;
> > + break;
> > +
> > + case MAPLE_TREE_SEARCH:
> > + maple_tree_ops.entry = do_maple_tree_search;
> > + break;
> > +
> > + case MAPLE_TREE_DUMP:
> > + maple_tree_ops.entry = do_maple_tree_dump;
> > + break;
> > +
> > + case MAPLE_TREE_GATHER:
> > + if (!(info.maxcount = rtp->index))
> > + info.maxcount = (ulong)(-1); /* caller beware */
> > +
> > + maple_tree_ops.entry = do_maple_tree_gather;
> > + break;
> > +
> > + case MAPLE_TREE_DUMP_CB:
> > + if (rtp->value == NULL) {
> > + error(FATAL, "do_maple_tree: need set callback function");
> > + return -EINVAL;
>
> The above "return" seems to be redundant.
Removed in v3.
Thanks,
Tao Liu
>
> Thanks.
> Lianbo
> > + }
> > + maple_tree_ops.entry = do_maple_tree_dump_cb;
> > + break;
> > +
> > + default:
> > + error(FATAL, "do_maple_tree: invalid flag: %lx\n", flag);
> > + }
> > +
> > + do_maple_tree_traverse(root, true);
> > + return info.count;
> > +}
> > +
> > /***********************************************/
> > void maple_init(void)
> > {
> > --
> > 2.33.1
>
More information about the Crash-utility
mailing list