On 7/9/24 15:32, Adrián Moreno wrote:
> On Tue, Jul 09, 2024 at 11:45:19AM GMT, Eelco Chaudron wrote:
>> On 7 Jul 2024, at 22:08, Adrian Moreno wrote:
>>
>>> Add a new resource in ofproto-dpif and the corresponding API in
>>> ofproto_provider.h to represent and local sampling configuration.
>>>
>>> Signed-off-by: Adrian Moreno <amore...@redhat.com>
>>
>> Some small nits below.
>>
>> //Eelco
>>
>>> ---
>>>  ofproto/automake.mk            |   2 +
>>>  ofproto/ofproto-dpif-lsample.c | 187 +++++++++++++++++++++++++++++++++
>>>  ofproto/ofproto-dpif-lsample.h |  36 +++++++
>>>  ofproto/ofproto-dpif.c         |  38 +++++++
>>>  ofproto/ofproto-dpif.h         |   1 +
>>>  ofproto/ofproto-provider.h     |   9 ++
>>>  ofproto/ofproto.c              |  12 +++
>>>  ofproto/ofproto.h              |   8 ++
>>>  8 files changed, 293 insertions(+)
>>>  create mode 100644 ofproto/ofproto-dpif-lsample.c
>>>  create mode 100644 ofproto/ofproto-dpif-lsample.h
>>>
>>> diff --git a/ofproto/automake.mk b/ofproto/automake.mk
>>> index 7c08b563b..cb1361b8a 100644
>>> --- a/ofproto/automake.mk
>>> +++ b/ofproto/automake.mk
>>> @@ -30,6 +30,8 @@ ofproto_libofproto_la_SOURCES = \
>>>     ofproto/ofproto-dpif.h \
>>>     ofproto/ofproto-dpif-ipfix.c \
>>>     ofproto/ofproto-dpif-ipfix.h \
>>> +   ofproto/ofproto-dpif-lsample.c \
>>> +   ofproto/ofproto-dpif-lsample.h \
>>>     ofproto/ofproto-dpif-mirror.c \
>>>     ofproto/ofproto-dpif-mirror.h \
>>>     ofproto/ofproto-dpif-monitor.c \
>>> diff --git a/ofproto/ofproto-dpif-lsample.c b/ofproto/ofproto-dpif-lsample.c
>>> new file mode 100644
>>> index 000000000..d675a116f
>>> --- /dev/null
>>> +++ b/ofproto/ofproto-dpif-lsample.c
>>> @@ -0,0 +1,187 @@
>>> +/*
>>> + * Copyright (c) 2024 Red Hat, Inc.
>>> + *
>>> + * Licensed under the Apache License, Version 2.0 (the "License");
>>> + * you may not use this file except in compliance with the License.
>>> + * You may obtain a copy of the License at:
>>> + *
>>> + *     http://www.apache.org/licenses/LICENSE-2.0
>>> + *
>>> + * Unless required by applicable law or agreed to in writing, software
>>> + * distributed under the License is distributed on an "AS IS" BASIS,
>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>>> + * See the License for the specific language governing permissions and
>>> + * limitations under the License.
>>> + */
>>> +
>>> +#include <config.h>
>>> +#include "ofproto-dpif-lsample.h"
>>> +
>>> +#include "cmap.h"
>>> +#include "hash.h"
>>> +#include "ofproto.h"
>>> +#include "openvswitch/thread.h"
>>> +
>>> +/* Dpif local sampling.
>>> + *
>>> + * Thread safety: dpif_lsample allows lockless concurrent reads of local
>>> + * sampling exporters as long as the following restrictions are met:
>>> + *   1) While the last reference is being dropped, i.e: a thread is calling
>>> + *      "dpif_lsample_unref" on the last reference, other threads cannot 
>>> call
>>> + *      "dpif_lsample_ref".
>>> + *   2) Threads do not quiese while holding references to internal
>>> + *      lsample_exporter objects.
>>> + */
>>> +
>>> +struct dpif_lsample {
>>> +    struct cmap exporters;          /* Contains lsample_exporter_node 
>>> instances
>>> +                                       indexed by collector_set_id. */
>>> +    struct ovs_mutex mutex;         /* Protects concurrent 
>>> insertion/deletion
>>> +                                     * of exporters. */
>>> +
>>> +    struct ovs_refcount ref_cnt;    /* Controls references to this 
>>> instance. */
>>> +};
>>> +
>>> +struct lsample_exporter {
>>> +    struct ofproto_lsample_options options;
>>> +};
>>> +
>>> +struct lsample_exporter_node {
>>> +    struct cmap_node node;              /* In dpif_lsample->exporters. */
>>> +    struct lsample_exporter exporter;
>>> +};
>>> +
>>> +static void
>>> +dpif_lsample_delete_exporter(struct dpif_lsample *lsample,
>>> +                             struct lsample_exporter_node *node)
>>> +{
>>> +    ovs_mutex_lock(&lsample->mutex);
>>> +    cmap_remove(&lsample->exporters, &node->node,
>>> +                hash_int(node->exporter.options.collector_set_id, 0));
>>> +    ovs_mutex_unlock(&lsample->mutex);
>>> +
>>> +    ovsrcu_postpone(free, node);
>>> +}
>>> +
>>> +/* Adds an exporter with the provided options which are copied. */
>>> +static struct lsample_exporter_node *
>>> +dpif_lsample_add_exporter(struct dpif_lsample *lsample,
>>> +                          const struct ofproto_lsample_options *options)
>>> +{
>>> +    struct lsample_exporter_node *node;
>>> +
>>> +    node = xzalloc(sizeof *node);
>>> +    node->exporter.options = *options;
>>> +
>>> +    ovs_mutex_lock(&lsample->mutex);
>>> +    cmap_insert(&lsample->exporters, &node->node,
>>> +                hash_int(options->collector_set_id, 0));
>>> +    ovs_mutex_unlock(&lsample->mutex);
>>> +
>>> +    return node;
>>> +}
>>> +
>>> +static struct lsample_exporter_node *
>>> +dpif_lsample_find_exporter_node(const struct dpif_lsample *lsample,
>>> +                                const uint32_t collector_set_id)
>>> +{
>>> +    struct lsample_exporter_node *node;
>>> +
>>> +    CMAP_FOR_EACH_WITH_HASH (node, node,
>>> +                            hash_int(collector_set_id, 0),
>>> +                            &lsample->exporters) {
>>> +        if (node->exporter.options.collector_set_id == collector_set_id) {
>>> +            return node;
>>> +        }
>>> +    }
>>> +    return NULL;
>>> +}
>>> +
>>> +/* Sets the lsample configuration and returns true if the configuration
>>> + * has changed. */
>>> +bool
>>> +dpif_lsample_set_options(struct dpif_lsample *lsample,
>>> +                         const struct ofproto_lsample_options *options,
>>> +                         size_t n_options)
>>> +{
>>> +    const struct ofproto_lsample_options *opt;
>>> +    struct lsample_exporter_node *node;
>>> +    bool changed = false;
>>> +    int i;
>>> +
>>> +    for (i = 0; i < n_options; i++) {
>>> +        opt = &options[i];
>>> +        node = dpif_lsample_find_exporter_node(lsample,
>>> +                                               opt->collector_set_id);
>>> +        if (!node) {
>>> +            dpif_lsample_add_exporter(lsample, opt);
>>> +            changed = true;
>>> +        } else if (memcmp(&node->exporter.options, opt, sizeof(*opt))) {
>>> +            dpif_lsample_delete_exporter(lsample, node);
>>> +            dpif_lsample_add_exporter(lsample, opt);
>>> +            changed = true;
>>> +        }
>>> +    }
>>> +
>>> +    /* Delete exporters that have been removed. */
>>> +    CMAP_FOR_EACH (node, node, &lsample->exporters) {
>>> +        for (i = 0; i < n_options; i++) {
>>> +            if (node->exporter.options.collector_set_id
>>> +                == options[i].collector_set_id) {
>>> +                break;
>>> +            }
>>> +        }
>>> +        if (i == n_options) {
>>> +            dpif_lsample_delete_exporter(lsample, node);
>>> +            changed = true;
>>> +        }
>>> +    }
>>> +
>>> +    return changed;
>>> +}
>>> +
>>> +struct dpif_lsample *
>>> +dpif_lsample_create(void)
>>> +{
>>> +    struct dpif_lsample *lsample;
>>> +
>>> +    lsample = xzalloc(sizeof *lsample);
>>> +    cmap_init(&lsample->exporters);
>>> +    ovs_mutex_init(&lsample->mutex);
>>> +    ovs_refcount_init(&lsample->ref_cnt);
>>> +
>>> +    return lsample;
>>> +}
>>> +
>>> +static void
>>> +dpif_lsample_destroy(struct dpif_lsample *lsample)
>>> +{
>>> +    if (lsample) {
>>> +        struct lsample_exporter_node *node;
>>> +
>>> +        CMAP_FOR_EACH (node, node, &lsample->exporters) {
>>> +            dpif_lsample_delete_exporter(lsample, node);
>>> +        }
>>> +        cmap_destroy(&lsample->exporters);
>>> +        free(lsample);
>>> +    }
>>> +}
>>> +
>>> +struct dpif_lsample *
>>> +dpif_lsample_ref(const struct dpif_lsample *lsample_)
>>> +{
>>> +    struct dpif_lsample *lsample = CONST_CAST(struct dpif_lsample *, 
>>> lsample_);
>>> +
>>> +    if (lsample) {
>>> +        ovs_refcount_ref(&lsample->ref_cnt);
>>> +    }
>>> +    return lsample;
>>> +}
>>> +
>>> +void
>>> +dpif_lsample_unref(struct dpif_lsample *lsample)
>>> +{
>>> +    if (lsample && ovs_refcount_unref_relaxed(&lsample->ref_cnt) == 1) {
>>> +        dpif_lsample_destroy(lsample);
>>> +    }
>>> +}
>>> diff --git a/ofproto/ofproto-dpif-lsample.h b/ofproto/ofproto-dpif-lsample.h
>>> new file mode 100644
>>> index 000000000..bee36c9c5
>>> --- /dev/null
>>> +++ b/ofproto/ofproto-dpif-lsample.h
>>> @@ -0,0 +1,36 @@
>>> +/*
>>> + * Copyright (c) 2024 Red Hat, Inc.
>>> + *
>>> + * Licensed under the Apache License, Version 2.0 (the "License");
>>> + * you may not use this file except in compliance with the License.
>>> + * You may obtain a copy of the License at:
>>> + *
>>> + *     http://www.apache.org/licenses/LICENSE-2.0
>>> + *
>>> + * Unless required by applicable law or agreed to in writing, software
>>> + * distributed under the License is distributed on an "AS IS" BASIS,
>>> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>>> + * See the License for the specific language governing permissions and
>>> + * limitations under the License.
>>> + */
>>> +
>>> +#ifndef OFPROTO_DPIF_LSAMPLE_H
>>> +#define OFPROTO_DPIF_LSAMPLE_H 1
>>> +
>>> +#include <stdbool.h>
>>> +#include <stdlib.h>
>>> +
>>> +struct dpif_lsample;
>>> +struct ofproto_lsample_options;
>>> +
>>> +struct dpif_lsample *dpif_lsample_create(void);
>>> +
>>> +void dpif_lsample_unref(struct dpif_lsample *);
>>> +
>>> +struct dpif_lsample *dpif_lsample_ref(const struct dpif_lsample *);
>>
>> I would define ref before unref.
>>
>>> +
>>> +bool dpif_lsample_set_options(struct dpif_lsample *,
>>> +                              const struct ofproto_lsample_options *,
>>> +                              size_t n_opts);
>>
>> Also not sure what would be the right way to group, not group, add extra
>> new lines in include files. Looks like we sort of group similar function,
>> and add new lines between groups. If we follow that it should probably look
>> something like this:
>>
>> struct dpif_lsample *dpif_lsample_create(void);
>>
>> struct dpif_lsample *dpif_lsample_ref(const struct dpif_lsample *);
>> void dpif_lsample_unref(struct dpif_lsample *);
>>
>> bool dpif_lsample_set_options(struct dpif_lsample *,
>>                               const struct ofproto_lsample_options *,
>>                               size_t n_opts);
>>
>> But I have no real preferences, maybe Ilya has.
>>
> 
> I don't either, your sorting looks good.

Grouping makes sense to me.

Best regards, Ilya Maximets.

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to