[ovs-dev] [PATCH v3 10/11] netdev: Add reconfigure request mechanism.

Daniele Di Proietto diproiettod at vmware.com
Wed Mar 16 23:04:52 UTC 2016



On 16/03/2016 06:12, "Ilya Maximets" <i.maximets at samsung.com> wrote:

>On 16.03.2016 01:30, Daniele Di Proietto wrote:
>> A netdev provider, especially a PMD provider (like netdev DPDK) might
>> not be able to change some of its parameters (such as MTU, or number of
>> queues) without stopping everything and restarting.
>> 
>> This commit introduces a mechanism that allows a netdev provider to
>> request a restart (netdev_request_reconfigure()).  The upper layer can
>> be notified via netdev_wait_reconf_required() and
>> netdev_is_reconf_required().  After closing all the rxqs the upper layer
>> can finally call netdev_reconfigure(), to make sure that the new
>> configuration is in place.
>> 
>> This will be used by next commit to reconfigure rx and tx queues in
>> netdev-dpdk.
>> 
>> Signed-off-by: Daniele Di Proietto <diproiettod at vmware.com>
>> ---
>>  lib/netdev-bsd.c      |  1 +
>>  lib/netdev-dpdk.c     |  1 +
>>  lib/netdev-dummy.c    |  1 +
>>  lib/netdev-linux.c    |  1 +
>>  lib/netdev-provider.h | 27 ++++++++++++++++++++++++++-
>>  lib/netdev-vport.c    |  1 +
>>  lib/netdev.c          | 38 ++++++++++++++++++++++++++++++++++++++
>>  lib/netdev.h          |  4 ++++
>>  8 files changed, 73 insertions(+), 1 deletion(-)
>> 
>> diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c
>> index edf04bf..724e6d4 100644
>> --- a/lib/netdev-bsd.c
>> +++ b/lib/netdev-bsd.c
>> @@ -1602,6 +1602,7 @@ netdev_bsd_update_flags(struct netdev *netdev_,
>>enum netdev_flags off,
>>      netdev_bsd_arp_lookup, /* arp_lookup */          \
>>                                                       \
>>      netdev_bsd_update_flags,                         \
>> +    NULL, /* reconfigure */                          \
>>                                                       \
>>      netdev_bsd_rxq_alloc,                            \
>>      netdev_bsd_rxq_construct,                        \
>> diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
>> index f402354..b5867e8 100644
>> --- a/lib/netdev-dpdk.c
>> +++ b/lib/netdev-dpdk.c
>> @@ -2696,6 +2696,7 @@ static const struct dpdk_qos_ops
>>egress_policer_ops = {
>>      NULL,                       /* arp_lookup */              \
>>                                                                \
>>      netdev_dpdk_update_flags,                                 \
>> +    NULL,                       /* reconfigure */             \
>>                                                                \
>>      netdev_dpdk_rxq_alloc,                                    \
>>      netdev_dpdk_rxq_construct,                                \
>> diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
>> index ccd4a0a..d7524eb 100644
>> --- a/lib/netdev-dummy.c
>> +++ b/lib/netdev-dummy.c
>> @@ -1251,6 +1251,7 @@ static const struct netdev_class dummy_class = {
>>      NULL,                       /* arp_lookup */
>>  
>>      netdev_dummy_update_flags,
>> +    NULL,                       /* reconfigure */
>>  
>>      netdev_dummy_rxq_alloc,
>>      netdev_dummy_rxq_construct,
>> diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
>> index 570677e..f9ad126 100644
>> --- a/lib/netdev-linux.c
>> +++ b/lib/netdev-linux.c
>> @@ -2897,6 +2897,7 @@ netdev_linux_update_flags(struct netdev *netdev_,
>>enum netdev_flags off,
>>      netdev_linux_arp_lookup,                                    \
>>                                                                  \
>>      netdev_linux_update_flags,                                  \
>> +    NULL,                       /* reconfigure */               \
>>                                                                  \
>>      netdev_linux_rxq_alloc,                                     \
>>      netdev_linux_rxq_construct,                                 \
>> diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
>> index 1952a02..0317910 100644
>> --- a/lib/netdev-provider.h
>> +++ b/lib/netdev-provider.h
>> @@ -52,6 +52,16 @@ struct netdev {
>>       * 'netdev''s flags, features, ethernet address, or carrier
>>changes. */
>>      uint64_t change_seq;
>>  
>> +    /* A netdev provider might be unable to change some of the device's
>> +     * parameter (n_rxq, mtu) when the device is in use.  In this case
>> +     * the provider can notify the upper layer by calling
>> +     * netdev_request_reconfigure().  The upper layer will react by
>>stopping
>> +     * the operations on the device and calling netdev_reconfigure()
>>to allow
>> +     * the configuration changes.  'last_reconfigure_seq' remembers
>>the value
>> +     * of 'reconfigure_seq' when the last reconfiguration happened. */
>> +    struct seq *reconfigure_seq;
>> +    uint64_t last_reconfigure_seq;
>> +
>>      /* The core netdev code initializes these at netdev construction
>>and only
>>       * provide read-only access to its client.  Netdev implementations
>>may
>>       * modify them. */
>> @@ -64,7 +74,7 @@ struct netdev {
>>      struct ovs_list saved_flags_list; /* Contains "struct
>>netdev_saved_flags". */
>>  };
>>  
>> -static void
>> +static inline void
>>  netdev_change_seq_changed(const struct netdev *netdev_)
>>  {
>>      struct netdev *netdev = CONST_CAST(struct netdev *, netdev_);
>> @@ -75,6 +85,12 @@ netdev_change_seq_changed(const struct netdev
>>*netdev_)
>>      }
>>  }
>>  
>> +static inline void
>> +netdev_request_reconfigure(struct netdev *netdev)
>> +{
>> +    seq_change(netdev->reconfigure_seq);
>> +}
>> +
>>  const char *netdev_get_type(const struct netdev *);
>>  const struct netdev_class *netdev_get_class(const struct netdev *);
>>  const char *netdev_get_name(const struct netdev *);
>> @@ -699,6 +715,15 @@ struct netdev_class {
>>      int (*update_flags)(struct netdev *netdev, enum netdev_flags off,
>>                          enum netdev_flags on, enum netdev_flags
>>*old_flags);
>>  
>> +    /* If the provider called netdev_request_reconfigure(), the upper
>>layer
>> +     * will eventually call this.  The provider can update the device
>> +     * configuration knowing that the upper layer will not call
>>rxq_recv() or
>> +     * send() until this function returns.
>> +     *
>> +     * On error, the configuration is indeterminant and the device
>>cannot be
>> +     * used to send and receive packets until a successful
>>configuration is
>> +     * applied. */
>> +    int (*reconfigure)(struct netdev *netdev);
>>  /* ## -------------------- ## */
>>  /* ## netdev_rxq Functions ## */
>>  /* ## -------------------- ## */
>> diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
>> index df6d8cf..d055f10 100644
>> --- a/lib/netdev-vport.c
>> +++ b/lib/netdev-vport.c
>> @@ -1537,6 +1537,7 @@ netdev_vport_range(struct unixctl_conn *conn, int
>>argc,
>>      NULL,                       /* arp_lookup */            \
>>                                                              \
>>      netdev_vport_update_flags,                              \
>> +    NULL,                       /* reconfigure */           \
>>                                                              \
>>      NULL,                   /* rx_alloc */                  \
>>      NULL,                   /* rx_construct */              \
>> diff --git a/lib/netdev.c b/lib/netdev.c
>> index 150f8d8..7cb7085 100644
>> --- a/lib/netdev.c
>> +++ b/lib/netdev.c
>> @@ -377,6 +377,8 @@ netdev_open(const char *name, const char *type,
>>struct netdev **netdevp)
>>                  netdev->netdev_class = rc->class;
>>                  netdev->name = xstrdup(name);
>>                  netdev->change_seq = 1;
>> +                netdev->reconfigure_seq = seq_create();
>> +                netdev->last_reconfigure_seq =
>>seq_read(netdev->reconfigure_seq);
>>                  netdev->node = shash_add(&netdev_shash, name, netdev);
>>  
>>                  /* By default enable one tx and rx queue per netdev. */
>> @@ -525,6 +527,7 @@ netdev_unref(struct netdev *dev)
>>              shash_delete(&netdev_shash, dev->node);
>>          }
>>          free(dev->name);
>> +        seq_destroy(dev->reconfigure_seq);
>>          dev->netdev_class->dealloc(dev);
>>          ovs_mutex_unlock(&netdev_mutex);
>>  
>> @@ -1854,3 +1857,38 @@ netdev_get_change_seq(const struct netdev
>>*netdev)
>>  {
>>      return netdev->change_seq;
>>  }
>> +
>> +void
>> +netdev_wait_reconf_required(struct netdev *netdev)
>> +{
>> +    seq_wait(netdev->reconfigure_seq, netdev->last_reconfigure_seq);
>> +}
>> +
>> +bool
>> +netdev_is_reconf_required(struct netdev *netdev)
>> +{
>> +    return seq_read(netdev->reconfigure_seq) !=
>>netdev->last_reconfigure_seq;
>> +}
>> +
>> +/* Give a chance to 'netdev' to reconfigure some of its parameters.
>> + *
>> + * If a module uses netdev_send() and netdev_rxq_recv(), it must call
>>this
>> + * function when netdev_is_reconf_required() returns true.
>> + *
>> + * Return 0 if successful, otherwise a positive errno value.  If the
>> + * reconfiguration fails the netdev will not be able to send or receive
>> + * packets.
>> + *
>> + * When this function is called, no concurrent call to
>>netdev_rxq_recv() or
>> + * netdev_send() must be issued. */
>
>Not only concurrent. There must be no calls at all.
>
>> +int
>> +netdev_reconfigure(struct netdev *netdev)
>> +{
>> +    const struct netdev_class *class = netdev->netdev_class;
>> +
>> +    netdev->last_reconfigure_seq = seq_read(netdev->reconfigure_seq);
>> +
>> +    return (class->reconfigure
>> +            ? class->reconfigure(netdev)
>> +            : EOPNOTSUPP);
>> +}
>> diff --git a/lib/netdev.h b/lib/netdev.h
>> index a81989e..c2a1d6c 100644
>> --- a/lib/netdev.h
>> +++ b/lib/netdev.h
>> @@ -308,6 +308,10 @@ int netdev_get_queue_stats(const struct netdev *,
>>unsigned int queue_id,
>>                             struct netdev_queue_stats *);
>>  uint64_t netdev_get_change_seq(const struct netdev *);
>>  
>> +int netdev_reconfigure(struct netdev *netdev);
>> +void netdev_wait_reconf_required(struct netdev *netdev);
>> +bool netdev_is_reconf_required(struct netdev *netdev);
>> +
>>  struct netdev_queue_dump {
>>      struct netdev *netdev;
>>      int error;
>> 




More information about the dev mailing list