[RFC net-next mlxsw v5] lib: Introduce manager for priority base pruning lookups between tables
Tal Bar
talb at mellanox.com
Tue Jun 12 01:41:08 AEST 2018
Thanks for the review.
Most of the comments are already taken care, I have few questions
On 05-Jun-18 5:40 PM, Jiri Pirko wrote:
> I went this throught quickly, I pointed out some obvious issues I can
> spot. Please fix before I will review any further. I would appreciate
> you do it in days. Every time you send a new version, my caches are
> already flushed and I start from scratch :/
I was in RD so couldn't complete it on days...
Anyhow now I have returned back to office so response should be quick now.
> My head is spinning a little bit... This seems quite complex that makes
> one wonder if the complexicity is really necessary.
>> +
>> +Database
>> +========
>> +Each prune object has a list of tables with mask.
>> +Each table consist:
>> + * hash table for items
>> + * list of the corresponding intersection tables (with other tables)
>> +Each intersection table consists of:
>> + * hash table for intersects items
>> + * each item contain two lists:
>> + 1. items of the table owner
>> + 2. items of other tables (neighbor) in the prune object.
>> +
>> +Synchronization & critical sections
>> +===================================
>> +library doesn't take responsibility on synchronization. it's the user
>> +responsibility to synchronize.
>> +
>> +Some of the APIs might sleep, please check the API headers for more information.
> No need. Remove this section. (I have a feeling that I already asked that)
This section is Synchronization & critical sections ? or also Database ?
Before that you have asked to remove the Synchronization from the APIs
not from here.
>
>> + * A*->A: Insert an item 'R' to a table, calculate its own prune-vector.
>> + * A->A*: 'R' was inserted to a table, and we have to calculate the
> I have no clue what "A" and "A*" is :O
It's just a notation for the direction of the the prune calculation
A*-->A: calculate my own rule
A-->A*: calculate other rules in the prune object.
>> + */
>> +
>> +#ifndef _PRUNE_H
>> +#define _PRUNE_H
>> +
>> +struct prune_table;
>> +struct prune;
>> +
>> +struct prune_item {
>> + unsigned long priority; /* Higher number means higher priority */
>> + unsigned long *mask;
>> + unsigned int mask_len; /* Number of bits */
>> + void *priv;
>> +};
>> +
>> +struct prune_vector_item {
> You don't use this outside prune.c. Please move it there.
I'm using it in test_prune.c
>> + struct prune_table *table;
>> + bool is_prune; /* True if item should prune this table otherwise not */
> Drop the "otherwise not".
>
> Is "is_prune" really the right name? Looks like "should_prune" is more
> accurate. If not, rather name it "is_pruned".
>
>
>> + struct list_head list;
>> + void *priv;
> When I see list_head and void *priv as a part of exported header, I'm
> starting to be really scarred...
Added an explanation to priv, you will see it in next version
it's the priv pf the table
>> +};
>> +
>> +struct prune_item_notify {
>> + struct prune_item item;
>> + /* list of prune vector item */
>> + const struct list_head *table_prune_list;
>> +};
>> +
>> +/**
>> + * This structure defines the management hooks for prune object.
>> + * The following hooks can be defined; unless noted otherwise, they are
>> + * optional and can be filled with a null pointer.
>> + *
>> + * prune_item_notify:
>> + * Called if there is a change in a the prune vector of an item or items,
>> + * the notification can be sent on one item or more.
>> + *
>> + * prune_mask_comparable:
>> + * Called when adding new items to a table.
>> + */
>> +struct prune_ops {
>> + void (*prune_item_notify)(struct prune_table *table,
>> + struct prune_item_notify *item,
>> + unsigned int item_cnt);
> item_cnt is set to 1 and never used. Why do you carry this? Please
> remove.
You are correct, it was used for notification aggregation but i have
change this interface so no longer needed.
>> + int (*prune_mask_comparable)(unsigned long *mask_a,
>> + unsigned long *mask_b,
>> + unsigned int len);
>> +};
>> +
>> +struct prune_table_attr {
>> + unsigned long *mask;
>> + unsigned int mask_len; /* Number of bits */
>> + /* Used by the priv field in strcut prune_table */
>> + void *priv;
>> +};
>> +
>> +struct prune *prune_init(unsigned int mask_len, const struct prune_ops *ops,
> "_init()" should be used for initialization in case you already has the
> object allocated (by "_alloc()" function). If you do 2 in 1, please use
> "_create()" and "_destroy()".
>
>
>> + void *priv);
>> +void prune_fini(struct prune *prune);
>> +struct prune_table *prune_table_add(struct prune *prune,
>> + struct prune_table_attr *table_attr);
> Again, since the table is allocated and initialized inside, do
> "_create()" and "_destroy()".
>
>
>
>> +int prune_table_remove(struct prune *prune, struct prune_table *table);
>> +int prune_item_add(struct prune *prune, struct prune_table *table,
>> + struct prune_item *item);
> Please always, if possible, avoid structs to be passed instead of
> simple args. In this case, just get rid of struct prune_item and pass
> all what you need as function args. You can then rename "struct
> prune_item_entry" to "struct prune_item". Also, I believe that you
> should rename this to "_create" and let the function return "struct
> prune_item_entry/struct prune_item". Later on the caller will use the
> returned pointer for destuction.
I understand the motivation here, the user doesn't need to allocate
prune_item, but if anyhow in the driver we already allocate it
the *mask filed for the rule, why does the library should do it again ?
Regarding struct prune_table_attr, should I remove it also ?
>> +int prune_item_remove(struct prune *prune, struct prune_table *table,
>> + struct prune_item *item);
> Should not return int. Just void. Please adjust the function and
> whatever is it calling.
What if this function fails ? should I add WARN(...) where it fails ?
>> +
>> +static bool prune_item_update(const struct list_head *table_prune_list,
>> + struct prune_table *corresponding_table,
>> + bool is_prune)
>> +{
>> + struct prune_vector_item *vector_item;
> So "item" or "vector_item". Make up your mind. Consistency, consistency,
> consistency!
There are two different structs one is prune_item the other one is
prune_vector_item.
what is not consistent here ? would you prefer prune_vector_elememt and
vector_elem ?
>> +
>> +static void
>> +prune_item_entry_to_item_notify(struct prune_item_notify *item_notify,
>> + struct prune_intersec_table_item *intersec_item)
>> +{
>> + const struct prune_table_item_entry *entry = intersec_item->entry;
>> +
>> + item_notify->item.priority = entry->ht_key.item->priority;
>> + item_notify->item.mask = entry->ht_key.item->mask;
>> + item_notify->item.mask_len = entry->ht_key.item->mask_len;
>> + item_notify->table_prune_list = &entry->table_prune_vector;
> It is really weird to take an internal list and expose it outside like
> this.
This is the reason I have const on this filed when it is exposed to the
user, otherwise I have to copy it. please advise
>> +}
>> +
>> +static bool
>> +prune_item_add_prune_vector_calc(struct prune_table *table,
> "prune_item_add_prune_vector_calc"? What is that.
> I think that I made myself clear that the function name should be
> always: "prefix_object_action".
The prefix here is "prune_item_add" since this func is being called from
an add flow, while the action here is calc which is being done on the
prune_vector
same goes with this function: prune_item_rem_prune_vector_calc
>
>> + * @table_handle: Add the item to this table identification.
>> + * @item: The item to add.
>> + *
>> + * Returns EPERM for invalid parameter
>> + * Returns ENOMEM in case allocation failed
>> + * Returns EEXIST if item already exists.
> These are pointless. Please remove.
Did you meant only for @table_handle or also for the error code ?
>> + * otherwise it returns 0.
>> + *
>> + * Note: all locking must be provided by the caller.
> "All locking"? Sounds really odd.
Actually I have took the phrasing from parman lib, should I change it to:
"It's the user responsibility to care for synchronization"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linux-mlxsw/attachments/20180611/83b054b9/attachment-0001.html>
More information about the Linux-mlxsw
mailing list