Thanks for your detailed comments, replies inline.

I'll send v4 in a minute.

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

>On 16.03.2016 01:30, Daniele Di Proietto wrote:
>> This introduces in dpif-netdev and netdev-dpdk the first use for the
>> newly introduce reconfigure netdev call.
>> 
>> When a request to change the number of queues comes, netdev-dpdk will
>> remember this and notify the upper layer via
>> netdev_request_reconfigure().
>> 
>> The datapath, instead of periodically calling netdev_set_multiq(), can
>> detect this and call reconfigure().
>> 
>> This mechanism can also be used to:
>> * Automatically match the number of rxq with the one provided by qemu
>>   via the new_device callback.
>> * Provide a way to change the MTU of dpdk devices at runtime.
>> 
>> Signed-off-by: Daniele Di Proietto <diproiet...@vmware.com>

[...]

>>
>> @@ -2637,8 +2577,79 @@ static const struct dpdk_qos_ops
>>egress_policer_ops = {
>>      egress_policer_run
>>  };
>>  
>> -#define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, DESTRUCT, MULTIQ,
>>SEND, \
>> -    GET_CARRIER, GET_STATS, GET_FEATURES, GET_STATUS, RXQ_RECV)
>>  \
>> +static int
>> +netdev_dpdk_reconfigure(struct netdev *netdev_)
>> +{
>> +    struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
>> +    int err = 0;
>> +
>> +    ovs_mutex_lock(&dpdk_mutex);
>> +    ovs_mutex_lock(&netdev->mutex);
>> +    rte_eth_dev_stop(netdev->port_id);
>
>Checking must be performed prior to stopping of device.

You're right, thanks for spotting that.

I fixed it

>
>> +
>> +    if (netdev_->n_txq == netdev->requested_n_txq
>> +        && netdev_->n_rxq == netdev->requested_n_rxq) {
>> +        /* Reconfiguration is unnecessary */
>> +
>> +        goto out;
>> +    }
>> +
>> +    netdev_->n_txq = netdev->requested_n_txq;
>> +    netdev_->n_rxq = netdev->requested_n_rxq;
>> +
>> +    rte_free(netdev->tx_q);
>> +    err = dpdk_eth_dev_init(netdev);
>> +    netdev_dpdk_alloc_txq(netdev, netdev->real_n_txq);
>> +
>> +    netdev->txq_needs_locking = netdev->real_n_txq != netdev->up.n_txq;
>> +
>> +out:
>> +
>> +    ovs_mutex_unlock(&netdev->mutex);
>> +    ovs_mutex_unlock(&dpdk_mutex);
>> +
>> +    return err;
>> +}
>> +
>> +static int
>> +netdev_dpdk_vhost_user_reconfigure(struct netdev *netdev_)
>> +{
>> +    struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
>> +
>> +    ovs_mutex_lock(&dpdk_mutex);
>> +    ovs_mutex_lock(&netdev->mutex);
>> +
>> +    netdev->up.n_txq = netdev->requested_n_txq;
>> +    netdev->up.n_rxq = netdev->requested_n_rxq;
>> +
>> +    ovs_mutex_unlock(&netdev->mutex);
>> +    ovs_mutex_unlock(&dpdk_mutex);
>> +
>> +    return 0;
>> +}
>> +
>> +static int
>> +netdev_dpdk_vhost_cuse_reconfigure(struct netdev *netdev_)
>> +{
>> +    struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
>> +
>> +    ovs_mutex_lock(&dpdk_mutex);
>> +    ovs_mutex_lock(&netdev->mutex);
>> +
>> +    netdev->up.n_txq = netdev->requested_n_txq;
>> +    netdev->real_n_txq = 1;
>> +    netdev->up.n_rxq = 1;
>> +    netdev->txq_needs_locking = netdev->real_n_txq != netdev->up.n_txq;
>> +
>> +    ovs_mutex_unlock(&netdev->mutex);
>> +    ovs_mutex_unlock(&dpdk_mutex);
>> +
>> +    return 0;
>> +}
>> +
>> +#define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, DESTRUCT, SEND, \
>> +                          GET_CARRIER, GET_STATS, GET_FEATURES,  \
>> +                          GET_STATUS, RECONFIGURE, RXQ_RECV)     \
>>  {                                                             \
>>      NAME,                                                     \
>>      INIT,                       /* init */                    \
>> @@ -2656,7 +2667,7 @@ static const struct dpdk_qos_ops
>>egress_policer_ops = {
>>      NULL,                       /* push header */             \
>>      NULL,                       /* pop header */              \
>>      netdev_dpdk_get_numa_id,    /* get_numa_id */             \
>> -    MULTIQ,                     /* set_multiq */              \
>> +    netdev_dpdk_set_multiq,                                   \
>>                                                                \
>>      SEND,                       /* send */                    \
>>      NULL,                       /* send_wait */               \
>> @@ -2696,7 +2707,7 @@ static const struct dpdk_qos_ops
>>egress_policer_ops = {
>>      NULL,                       /* arp_lookup */              \
>>                                                                \
>>      netdev_dpdk_update_flags,                                 \
>> -    NULL,                       /* reconfigure */             \
>> +    RECONFIGURE,                                              \
>>                                                                \
>>      netdev_dpdk_rxq_alloc,                                    \
>>      netdev_dpdk_rxq_construct,                                \
>> @@ -2811,12 +2822,12 @@ static const struct netdev_class dpdk_class =
>>          NULL,
>>          netdev_dpdk_construct,
>>          netdev_dpdk_destruct,
>> -        netdev_dpdk_set_multiq,
>>          netdev_dpdk_eth_send,
>>          netdev_dpdk_get_carrier,
>>          netdev_dpdk_get_stats,
>>          netdev_dpdk_get_features,
>>          netdev_dpdk_get_status,
>> +        netdev_dpdk_reconfigure,
>>          netdev_dpdk_rxq_recv);
>>  
>>  static const struct netdev_class dpdk_ring_class =
>> @@ -2825,12 +2836,12 @@ static const struct netdev_class
>>dpdk_ring_class =
>>          NULL,
>>          netdev_dpdk_ring_construct,
>>          netdev_dpdk_destruct,
>> -        netdev_dpdk_set_multiq,
>>          netdev_dpdk_ring_send,
>>          netdev_dpdk_get_carrier,
>>          netdev_dpdk_get_stats,
>>          netdev_dpdk_get_features,
>>          netdev_dpdk_get_status,
>> +        netdev_dpdk_reconfigure,
>>          netdev_dpdk_rxq_recv);
>>  
>>  static const struct netdev_class OVS_UNUSED dpdk_vhost_cuse_class =
>> @@ -2839,12 +2850,12 @@ static const struct netdev_class OVS_UNUSED
>>dpdk_vhost_cuse_class =
>>          dpdk_vhost_cuse_class_init,
>>          netdev_dpdk_vhost_cuse_construct,
>>          netdev_dpdk_vhost_destruct,
>> -        netdev_dpdk_vhost_cuse_set_multiq,
>>          netdev_dpdk_vhost_send,
>>          netdev_dpdk_vhost_get_carrier,
>>          netdev_dpdk_vhost_get_stats,
>>          NULL,
>>          NULL,
>> +        netdev_dpdk_vhost_cuse_reconfigure,
>>          netdev_dpdk_vhost_rxq_recv);
>>  
>>  static const struct netdev_class OVS_UNUSED dpdk_vhost_user_class =
>> @@ -2853,12 +2864,12 @@ static const struct netdev_class OVS_UNUSED
>>dpdk_vhost_user_class =
>>          dpdk_vhost_user_class_init,
>>          netdev_dpdk_vhost_user_construct,
>>          netdev_dpdk_vhost_destruct,
>> -        netdev_dpdk_vhost_set_multiq,
>>          netdev_dpdk_vhost_send,
>>          netdev_dpdk_vhost_get_carrier,
>>          netdev_dpdk_vhost_get_stats,
>>          NULL,
>>          NULL,
>> +        netdev_dpdk_vhost_user_reconfigure,
>>          netdev_dpdk_vhost_rxq_recv);
>>  
>>  void
>> diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
>> index 0317910..ea40d61 100644
>> --- a/lib/netdev-provider.h
>> +++ b/lib/netdev-provider.h
>> @@ -67,8 +67,6 @@ struct netdev {
>>       * modify them. */
>>      int n_txq;
>>      int n_rxq;
>> -    /* Number of rx queues requested by user. */
>> -    int requested_n_rxq;
>>      int ref_cnt;                        /* Times this devices was
>>opened. */
>>      struct shash_node *node;            /* Pointer to element in
>>global map. */
>>      struct ovs_list saved_flags_list; /* Contains "struct
>>netdev_saved_flags". */
>> @@ -295,13 +293,8 @@ struct netdev_class {
>>       * such info, returns NETDEV_NUMA_UNSPEC. */
>>      int (*get_numa_id)(const struct netdev *netdev);
>>  
>> -    /* Configures the number of tx queues and rx queues of 'netdev'.
>> -     * Return 0 if successful, otherwise a positive errno value.
>> -     *
>> -     * 'n_rxq' specifies the maximum number of receive queues to
>>create.
>> -     * The netdev provider might choose to create less (e.g. if the
>>hardware
>> -     * supports only a smaller number).  The actual number of queues
>>created
>> -     * is stored in the 'netdev->n_rxq' field.
>> +    /* Configures the number of tx queues of 'netdev'. Returns 0 if
>>successful,
>> +     * otherwise a positive errno value.
>>       *
>>       * 'n_txq' specifies the exact number of transmission queues to
>>create.
>>       * The caller will call netdev_send() concurrently from 'n_txq'
>>different
>> @@ -309,12 +302,8 @@ struct netdev_class {
>>       * making sure that these concurrent calls do not create a race
>>condition
>>       * by using multiple hw queues or locking.
>
>Comment above (a little corrupted by diff) needs to be rewritten because
>of
>undocumented relations between 'set_multiq' and 'reconfigure' calls
>described in
>my next comment.

You're right, I've added the following paragraph:

* The caller will call netdev_reconfigure() (if necessary) before using
     * netdev_send() on any of the newly configured queues, giving the
provider
     * a chance to adjust its settings.



>
>>       *
>> -     * On error, the tx queue and rx queue configuration is
>>indeterminant.
>> -     * Caller should make decision on whether to restore the previous
>>or
>> -     * the default configuration.  Also, caller must make sure there
>>is no
>> -     * other thread accessing the queues at the same time. */
>> -    int (*set_multiq)(struct netdev *netdev, unsigned int n_txq,
>> -                      unsigned int n_rxq);
>> +     * On error, the tx queue configuration is unchanged. */
>> +    int (*set_multiq)(struct netdev *netdev, unsigned int n_txq);
>>  
>>      /* Sends buffers on 'netdev'.
>>       * Returns 0 if successful (for every buffer), otherwise a
>>positive errno
>> diff --git a/lib/netdev.c b/lib/netdev.c
>> index 7cb7085..8c1d7a4 100644
>> --- a/lib/netdev.c
>> +++ b/lib/netdev.c
>> @@ -106,12 +106,6 @@ netdev_n_rxq(const struct netdev *netdev)
>>      return netdev->n_rxq;
>>  }
>>  
>> -int
>> -netdev_requested_n_rxq(const struct netdev *netdev)
>> -{
>> -    return netdev->requested_n_rxq;
>> -}
>> -
>>  bool
>>  netdev_is_pmd(const struct netdev *netdev)
>>  {
>> @@ -384,7 +378,6 @@ netdev_open(const char *name, const char *type,
>>struct netdev **netdevp)
>>                  /* By default enable one tx and rx queue per netdev. */
>>                  netdev->n_txq = netdev->netdev_class->send ? 1 : 0;
>>                  netdev->n_rxq = netdev->netdev_class->rxq_alloc ? 1 :
>>0;
>> -                netdev->requested_n_rxq = netdev->n_rxq;
>>  
>>                  list_init(&netdev->saved_flags_list);
>>  
>> @@ -685,37 +678,26 @@ netdev_rxq_drain(struct netdev_rxq *rx)
>>              : 0);
>>  }
>>  
>> -/* Configures the number of tx queues and rx queues of 'netdev'.
>> - * Return 0 if successful, otherwise a positive errno value.
>> - *
>> - * 'n_rxq' specifies the maximum number of receive queues to create.
>> - * The netdev provider might choose to create less (e.g. if the
>>hardware
>> - * supports only a smaller number).  The caller can check how many
>>have been
>> - * actually created by calling 'netdev_n_rxq()'
>> +/* Configures the number of tx queues of 'netdev'. Returns 0 if
>>successful,
>> + * otherwise a positive errno value.
>>   *
>>   * 'n_txq' specifies the exact number of transmission queues to create.
>>   * If this function returns successfully, the caller can make 'n_txq'
>>   * concurrent calls to netdev_send() (each one with a different 'qid'
>>in the
>>   * range [0..'n_txq'-1]).
>
>This is not true now. The caller can make concurrent calls to
>netdev_send()
>only after successful netdev_reconfigure().

Good point, we have to document this interface change.

I've added this paragraph:

* The change might not effective immediately.  The caller must check if a
 * reconfiguration is required with netdev_is_reconf_required() and
eventually
 * call netdev_reconfigure() before using the new queues.



>
>>   *
>> - * On error, the tx queue and rx queue configuration is indeterminant.
>> - * Caller should make decision on whether to restore the previous or
>> - * the default configuration.  Also, caller must make sure there is no
>> - * other thread accessing the queues at the same time. */
>> + * On error, the tx queue configuration is unchanged */
>>  int
>> -netdev_set_multiq(struct netdev *netdev, unsigned int n_txq,
>> -                  unsigned int n_rxq)
>> +netdev_set_multiq(struct netdev *netdev, unsigned int n_txq)
>>  {
>>      int error;
>>  
>>      error = (netdev->netdev_class->set_multiq
>> -             ? netdev->netdev_class->set_multiq(netdev,
>> -                                                MAX(n_txq, 1),
>> -                                                MAX(n_rxq, 1))
>> +             ? netdev->netdev_class->set_multiq(netdev, MAX(n_txq, 1))
>>               : EOPNOTSUPP);
>>  
>>      if (error && error != EOPNOTSUPP) {
>> -        VLOG_DBG_RL(&rl, "failed to set tx/rx queue for network device
>>%s:"
>> +        VLOG_DBG_RL(&rl, "failed to set tx queue for network device
>>%s:"
>>                      "%s", netdev_get_name(netdev),
>>ovs_strerror(error));
>>      }
>>  
>> diff --git a/lib/netdev.h b/lib/netdev.h
>> index c2a1d6c..bb3d297 100644
>> --- a/lib/netdev.h
>> +++ b/lib/netdev.h
>> @@ -142,7 +142,6 @@ bool netdev_is_reserved_name(const char *name);
>>  
>>  int netdev_n_txq(const struct netdev *netdev);
>>  int netdev_n_rxq(const struct netdev *netdev);
>> -int netdev_requested_n_rxq(const struct netdev *netdev);
>>  bool netdev_is_pmd(const struct netdev *netdev);
>>  
>>  /* Open and close. */
>> @@ -168,7 +167,7 @@ const char *netdev_get_type_from_name(const char *);
>>  int netdev_get_mtu(const struct netdev *, int *mtup);
>>  int netdev_set_mtu(const struct netdev *, int mtu);
>>  int netdev_get_ifindex(const struct netdev *);
>> -int netdev_set_multiq(struct netdev *, unsigned int n_txq, unsigned
>>int n_rxq);
>> +int netdev_set_multiq(struct netdev *, unsigned int n_txq);
>>  
>>  /* Packet reception. */
>>  int netdev_rxq_open(struct netdev *, struct netdev_rxq **, int id);
>> 

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to