diff mbox

[ovs-dev,v4] dpif-netdev: Change definitions of 'idle' & 'processing' cycles

Message ID 1487595180-5239-1-git-send-email-ciara.loftus@intel.com
State Accepted
Delegated to: Darrell Ball
Headers show

Commit Message

Ciara Loftus Feb. 20, 2017, 12:53 p.m. UTC
Instead of counting all polling cycles as processing cycles, only count
the cycles where packets were received from the polling.

Signed-off-by: Georg Schmuecking <georg.schmuecking@ericsson.com>
Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
Co-authored-by: Georg Schmuecking <georg.schmuecking@ericsson.com>
Acked-by: Kevin Traynor <ktraynor@redhat.com>
---
v4:
- Move call to cycles_count_intermediate in order to collect more
  accurate statistics.
v3:
- Updated acks & co-author tags
- Removed unnecessary PMD_CYCLES_POLLING counter type
- Explain terms 'idle' and 'processing' cycles in
  vswitchd/ovs-vswitchd.8.in
v2:
- Rebase

 lib/dpif-netdev.c          | 58 +++++++++++++++++++++++++++++++++++-----------
 vswitchd/ovs-vswitchd.8.in |  5 +++-
 2 files changed, 48 insertions(+), 15 deletions(-)

Comments

Stokes, Ian May 26, 2017, 2:13 p.m. UTC | #1
> Instead of counting all polling cycles as processing cycles, only count
> the cycles where packets were received from the polling.
> 
> Signed-off-by: Georg Schmuecking <georg.schmuecking@ericsson.com>
> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
> Co-authored-by: Georg Schmuecking <georg.schmuecking@ericsson.com>
> Acked-by: Kevin Traynor <ktraynor@redhat.com>
> ---
> v4:
> - Move call to cycles_count_intermediate in order to collect more
>   accurate statistics.
> v3:
> - Updated acks & co-author tags
> - Removed unnecessary PMD_CYCLES_POLLING counter type
> - Explain terms 'idle' and 'processing' cycles in
>   vswitchd/ovs-vswitchd.8.in
> v2:
> - Rebase
> 
>  lib/dpif-netdev.c          | 58 +++++++++++++++++++++++++++++++++++------
> -----
>  vswitchd/ovs-vswitchd.8.in |  5 +++-
>  2 files changed, 48 insertions(+), 15 deletions(-)
> 
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 30907b7..a80ffb2
> 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -279,8 +279,9 @@ enum dp_stat_type {
>  };
> 
>  enum pmd_cycles_counter_type {
> -    PMD_CYCLES_POLLING,         /* Cycles spent polling NICs. */
> -    PMD_CYCLES_PROCESSING,      /* Cycles spent processing packets */
> +    PMD_CYCLES_IDLE,            /* Cycles spent idle or unsuccessful
> polling */
> +    PMD_CYCLES_PROCESSING,      /* Cycles spent successfully polling and
> +                                 * processing polled packets */
>      PMD_N_CYCLES
>  };
> 
> @@ -755,10 +756,10 @@ pmd_info_show_stats(struct ds *reply,
>      }
> 
>      ds_put_format(reply,
> -                  "\tpolling cycles:%"PRIu64" (%.02f%%)\n"
> +                  "\tidle cycles:%"PRIu64" (%.02f%%)\n"
>                    "\tprocessing cycles:%"PRIu64" (%.02f%%)\n",
> -                  cycles[PMD_CYCLES_POLLING],
> -                  cycles[PMD_CYCLES_POLLING] / (double)total_cycles *
> 100,
> +                  cycles[PMD_CYCLES_IDLE],
> +                  cycles[PMD_CYCLES_IDLE] / (double)total_cycles * 100,
>                    cycles[PMD_CYCLES_PROCESSING],
>                    cycles[PMD_CYCLES_PROCESSING] / (double)total_cycles *
> 100);
> 
> @@ -2953,30 +2954,43 @@ cycles_count_end(struct dp_netdev_pmd_thread *pmd,
>      non_atomic_ullong_add(&pmd->cycles.n[type], interval);  }
> 
> -static void
> +/* Calculate the intermediate cycle result and add to the counter
> +'type' */ static inline void cycles_count_intermediate(struct
> +dp_netdev_pmd_thread *pmd,
> +                          enum pmd_cycles_counter_type type)
> +    OVS_NO_THREAD_SAFETY_ANALYSIS
> +{
> +    unsigned long long new_cycles = cycles_counter();
> +    unsigned long long interval = new_cycles - pmd->last_cycles;
> +    pmd->last_cycles = new_cycles;
> +
> +    non_atomic_ullong_add(&pmd->cycles.n[type], interval); }
> +
> +static int
>  dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
>                             struct netdev_rxq *rx,
>                             odp_port_t port_no)  {
>      struct dp_packet_batch batch;
>      int error;
> +    int batch_cnt = 0;
> 
>      dp_packet_batch_init(&batch);
> -    cycles_count_start(pmd);
>      error = netdev_rxq_recv(rx, &batch);
> -    cycles_count_end(pmd, PMD_CYCLES_POLLING);
>      if (!error) {
>          *recirc_depth_get() = 0;
> 
> -        cycles_count_start(pmd);
> +        batch_cnt = batch.count;
>          dp_netdev_input(pmd, &batch, port_no);
> -        cycles_count_end(pmd, PMD_CYCLES_PROCESSING);
>      } else if (error != EAGAIN && error != EOPNOTSUPP) {
>          static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
> 
>          VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
>                      netdev_rxq_get_name(rx), ovs_strerror(error));
>      }
> +
> +    return batch_cnt;
>  }
> 
>  static struct tx_port *
> @@ -3438,21 +3452,29 @@ dpif_netdev_run(struct dpif *dpif)
>      struct dp_netdev *dp = get_dp_netdev(dpif);
>      struct dp_netdev_pmd_thread *non_pmd;
>      uint64_t new_tnl_seq;
> +    int process_packets = 0;
> 
>      ovs_mutex_lock(&dp->port_mutex);
>      non_pmd = dp_netdev_get_pmd(dp, NON_PMD_CORE_ID);
>      if (non_pmd) {
>          ovs_mutex_lock(&dp->non_pmd_mutex);
> +        cycles_count_start(non_pmd);
>          HMAP_FOR_EACH (port, node, &dp->ports) {
>              if (!netdev_is_pmd(port->netdev)) {
>                  int i;
> 
>                  for (i = 0; i < port->n_rxq; i++) {
> -                    dp_netdev_process_rxq_port(non_pmd, port->rxqs[i].rx,
> -                                               port->port_no);
> +                    process_packets =
> +                        dp_netdev_process_rxq_port(non_pmd,
> +                                                   port->rxqs[i].rx,
> +                                                   port->port_no);
> +                    cycles_count_intermediate(non_pmd, process_packets ?
> +
> PMD_CYCLES_PROCESSING
> +                                                     :
> + PMD_CYCLES_IDLE);
>                  }
>              }
>          }
> +        cycles_count_end(non_pmd, PMD_CYCLES_IDLE);
>          dpif_netdev_xps_revalidate_pmd(non_pmd, time_msec(), false);
>          ovs_mutex_unlock(&dp->non_pmd_mutex);
> 
> @@ -3577,6 +3599,7 @@ pmd_thread_main(void *f_)
>      bool exiting;
>      int poll_cnt;
>      int i;
> +    int process_packets = 0;
> 
>      poll_list = NULL;
> 
> @@ -3603,10 +3626,15 @@ reload:
>          lc = UINT_MAX;
>      }
> 
> +    cycles_count_start(pmd);
>      for (;;) {
>          for (i = 0; i < poll_cnt; i++) {
> -            dp_netdev_process_rxq_port(pmd, poll_list[i].rx,
> -                                       poll_list[i].port_no);
> +            process_packets =
> +                dp_netdev_process_rxq_port(pmd, poll_list[i].rx,
> +                                           poll_list[i].port_no);
> +            cycles_count_intermediate(pmd,
> +                                      process_packets ?
> PMD_CYCLES_PROCESSING
> +                                                      :
> + PMD_CYCLES_IDLE);
>          }
> 
>          if (lc++ > 1024) {
> @@ -3627,6 +3655,8 @@ reload:
>          }
>      }
> 
> +    cycles_count_end(pmd, PMD_CYCLES_IDLE);
> +
>      poll_cnt = pmd_load_queues_and_ports(pmd, &poll_list);
>      exiting = latch_is_set(&pmd->exit_latch);
>      /* Signal here to make sure the pmd finishes diff --git
> a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index
> fc19f3b..2e6e684 100644
> --- a/vswitchd/ovs-vswitchd.8.in
> +++ b/vswitchd/ovs-vswitchd.8.in
> @@ -253,7 +253,10 @@ The sum of ``emc hits'', ``masked hits'' and ``miss''
> is the number of  packets received by the datapath.  Cycles are counted
> using the TSC or similar  facilities (when available on the platform).  To
> reset these counters use  \fBdpif-netdev/pmd-stats-clear\fR. The duration
> of one cycle depends on the -measuring infrastructure.
> +measuring infrastructure. ``idle cycles'' refers to cycles spent
> +polling devices but not receiving any packets. ``processing cycles''
> +refers to cycles spent polling devices and sucessfully receiving

Typo above in 'sucessfully'

> +packets, plus the cycles spent processing said packets.
>  .IP "\fBdpif-netdev/pmd-stats-clear\fR [\fIdp\fR]"
>  Resets to zero the per pmd thread performance numbers shown by the
> \fBdpif-netdev/pmd-stats-show\fR command.  It will NOT reset datapath or
> --

Other than that LGTM. I've tested behavior and verified compilation with gcc, clang and sparse.

Acked-by: Ian Stokes <ian.stokes@intel.com>
Tested-by: Ian Stokes <ian.stokes@intel.com>
Darrell Ball June 2, 2017, 2:28 a.m. UTC | #2
Aside from Ian’s typo comment, which could be fixed on application.

Acked-by: Darrell Ball <dlu998@gmail.com>


I tested a few scenarios to see if the numbers made sense.



On 5/26/17, 7:13 AM, "ovs-dev-bounces@openvswitch.org on behalf of Stokes, Ian" <ovs-dev-bounces@openvswitch.org on behalf of ian.stokes@intel.com> wrote:

    > Instead of counting all polling cycles as processing cycles, only count

    > the cycles where packets were received from the polling.

    > 

    > Signed-off-by: Georg Schmuecking <georg.schmuecking@ericsson.com>

    > Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>

    > Co-authored-by: Georg Schmuecking <georg.schmuecking@ericsson.com>

    > Acked-by: Kevin Traynor <ktraynor@redhat.com>

    > ---

    > v4:

    > - Move call to cycles_count_intermediate in order to collect more

    >   accurate statistics.

    > v3:

    > - Updated acks & co-author tags

    > - Removed unnecessary PMD_CYCLES_POLLING counter type

    > - Explain terms 'idle' and 'processing' cycles in

    >   vswitchd/ovs-vswitchd.8.in

    > v2:

    > - Rebase

    > 

    >  lib/dpif-netdev.c          | 58 +++++++++++++++++++++++++++++++++++------

    > -----

    >  vswitchd/ovs-vswitchd.8.in |  5 +++-

    >  2 files changed, 48 insertions(+), 15 deletions(-)

    > 

    > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 30907b7..a80ffb2

    > 100644

    > --- a/lib/dpif-netdev.c

    > +++ b/lib/dpif-netdev.c

    > @@ -279,8 +279,9 @@ enum dp_stat_type {

    >  };

    > 

    >  enum pmd_cycles_counter_type {

    > -    PMD_CYCLES_POLLING,         /* Cycles spent polling NICs. */

    > -    PMD_CYCLES_PROCESSING,      /* Cycles spent processing packets */

    > +    PMD_CYCLES_IDLE,            /* Cycles spent idle or unsuccessful

    > polling */

    > +    PMD_CYCLES_PROCESSING,      /* Cycles spent successfully polling and

    > +                                 * processing polled packets */

    >      PMD_N_CYCLES

    >  };

    > 

    > @@ -755,10 +756,10 @@ pmd_info_show_stats(struct ds *reply,

    >      }

    > 

    >      ds_put_format(reply,

    > -                  "\tpolling cycles:%"PRIu64" (%.02f%%)\n"

    > +                  "\tidle cycles:%"PRIu64" (%.02f%%)\n"

    >                    "\tprocessing cycles:%"PRIu64" (%.02f%%)\n",

    > -                  cycles[PMD_CYCLES_POLLING],

    > -                  cycles[PMD_CYCLES_POLLING] / (double)total_cycles *

    > 100,

    > +                  cycles[PMD_CYCLES_IDLE],

    > +                  cycles[PMD_CYCLES_IDLE] / (double)total_cycles * 100,

    >                    cycles[PMD_CYCLES_PROCESSING],

    >                    cycles[PMD_CYCLES_PROCESSING] / (double)total_cycles *

    > 100);

    > 

    > @@ -2953,30 +2954,43 @@ cycles_count_end(struct dp_netdev_pmd_thread *pmd,

    >      non_atomic_ullong_add(&pmd->cycles.n[type], interval);  }

    > 

    > -static void

    > +/* Calculate the intermediate cycle result and add to the counter

    > +'type' */ static inline void cycles_count_intermediate(struct

    > +dp_netdev_pmd_thread *pmd,

    > +                          enum pmd_cycles_counter_type type)

    > +    OVS_NO_THREAD_SAFETY_ANALYSIS

    > +{

    > +    unsigned long long new_cycles = cycles_counter();

    > +    unsigned long long interval = new_cycles - pmd->last_cycles;

    > +    pmd->last_cycles = new_cycles;

    > +

    > +    non_atomic_ullong_add(&pmd->cycles.n[type], interval); }

    > +

    > +static int

    >  dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,

    >                             struct netdev_rxq *rx,

    >                             odp_port_t port_no)  {

    >      struct dp_packet_batch batch;

    >      int error;

    > +    int batch_cnt = 0;

    > 

    >      dp_packet_batch_init(&batch);

    > -    cycles_count_start(pmd);

    >      error = netdev_rxq_recv(rx, &batch);

    > -    cycles_count_end(pmd, PMD_CYCLES_POLLING);

    >      if (!error) {

    >          *recirc_depth_get() = 0;

    > 

    > -        cycles_count_start(pmd);

    > +        batch_cnt = batch.count;

    >          dp_netdev_input(pmd, &batch, port_no);

    > -        cycles_count_end(pmd, PMD_CYCLES_PROCESSING);

    >      } else if (error != EAGAIN && error != EOPNOTSUPP) {

    >          static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);

    > 

    >          VLOG_ERR_RL(&rl, "error receiving data from %s: %s",

    >                      netdev_rxq_get_name(rx), ovs_strerror(error));

    >      }

    > +

    > +    return batch_cnt;

    >  }

    > 

    >  static struct tx_port *

    > @@ -3438,21 +3452,29 @@ dpif_netdev_run(struct dpif *dpif)

    >      struct dp_netdev *dp = get_dp_netdev(dpif);

    >      struct dp_netdev_pmd_thread *non_pmd;

    >      uint64_t new_tnl_seq;

    > +    int process_packets = 0;

    > 

    >      ovs_mutex_lock(&dp->port_mutex);

    >      non_pmd = dp_netdev_get_pmd(dp, NON_PMD_CORE_ID);

    >      if (non_pmd) {

    >          ovs_mutex_lock(&dp->non_pmd_mutex);

    > +        cycles_count_start(non_pmd);

    >          HMAP_FOR_EACH (port, node, &dp->ports) {

    >              if (!netdev_is_pmd(port->netdev)) {

    >                  int i;

    > 

    >                  for (i = 0; i < port->n_rxq; i++) {

    > -                    dp_netdev_process_rxq_port(non_pmd, port->rxqs[i].rx,

    > -                                               port->port_no);

    > +                    process_packets =

    > +                        dp_netdev_process_rxq_port(non_pmd,

    > +                                                   port->rxqs[i].rx,

    > +                                                   port->port_no);

    > +                    cycles_count_intermediate(non_pmd, process_packets ?

    > +

    > PMD_CYCLES_PROCESSING

    > +                                                     :

    > + PMD_CYCLES_IDLE);

    >                  }

    >              }

    >          }

    > +        cycles_count_end(non_pmd, PMD_CYCLES_IDLE);

    >          dpif_netdev_xps_revalidate_pmd(non_pmd, time_msec(), false);

    >          ovs_mutex_unlock(&dp->non_pmd_mutex);

    > 

    > @@ -3577,6 +3599,7 @@ pmd_thread_main(void *f_)

    >      bool exiting;

    >      int poll_cnt;

    >      int i;

    > +    int process_packets = 0;

    > 

    >      poll_list = NULL;

    > 

    > @@ -3603,10 +3626,15 @@ reload:

    >          lc = UINT_MAX;

    >      }

    > 

    > +    cycles_count_start(pmd);

    >      for (;;) {

    >          for (i = 0; i < poll_cnt; i++) {

    > -            dp_netdev_process_rxq_port(pmd, poll_list[i].rx,

    > -                                       poll_list[i].port_no);

    > +            process_packets =

    > +                dp_netdev_process_rxq_port(pmd, poll_list[i].rx,

    > +                                           poll_list[i].port_no);

    > +            cycles_count_intermediate(pmd,

    > +                                      process_packets ?

    > PMD_CYCLES_PROCESSING

    > +                                                      :

    > + PMD_CYCLES_IDLE);

    >          }

    > 

    >          if (lc++ > 1024) {

    > @@ -3627,6 +3655,8 @@ reload:

    >          }

    >      }

    > 

    > +    cycles_count_end(pmd, PMD_CYCLES_IDLE);

    > +

    >      poll_cnt = pmd_load_queues_and_ports(pmd, &poll_list);

    >      exiting = latch_is_set(&pmd->exit_latch);

    >      /* Signal here to make sure the pmd finishes diff --git

    > a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index

    > fc19f3b..2e6e684 100644

    > --- a/vswitchd/ovs-vswitchd.8.in

    > +++ b/vswitchd/ovs-vswitchd.8.in

    > @@ -253,7 +253,10 @@ The sum of ``emc hits'', ``masked hits'' and ``miss''

    > is the number of  packets received by the datapath.  Cycles are counted

    > using the TSC or similar  facilities (when available on the platform).  To

    > reset these counters use  \fBdpif-netdev/pmd-stats-clear\fR. The duration

    > of one cycle depends on the -measuring infrastructure.

    > +measuring infrastructure. ``idle cycles'' refers to cycles spent

    > +polling devices but not receiving any packets. ``processing cycles''

    > +refers to cycles spent polling devices and sucessfully receiving

    
    Typo above in 'sucessfully'
    
    > +packets, plus the cycles spent processing said packets.

    >  .IP "\fBdpif-netdev/pmd-stats-clear\fR [\fIdp\fR]"

    >  Resets to zero the per pmd thread performance numbers shown by the

    > \fBdpif-netdev/pmd-stats-show\fR command.  It will NOT reset datapath or

    > --

    
    Other than that LGTM. I've tested behavior and verified compilation with gcc, clang and sparse.
    
    Acked-by: Ian Stokes <ian.stokes@intel.com>

    Tested-by: Ian Stokes <ian.stokes@intel.com>

    _______________________________________________
    dev mailing list
    dev@openvswitch.org
    https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwICAg&c=uilaK90D4TOVoH58JNXRgQ&r=BVhFA09CGX7JQ5Ih-uZnsw&m=qsZ_NICrLITF6gtbrgjmBHvJDaCKMm8iJJsPyW8cYvE&s=p6LdM8QboVckrfzxHNVr7iB8aA7PMyY_1QJCibU-I-I&e=
Ben Pfaff July 6, 2017, 11:50 p.m. UTC | #3
I'm a little puzzled why no one has been yelling at me to apply this,
but anyway I did it now.

On Fri, Jun 02, 2017 at 02:28:08AM +0000, Darrell Ball wrote:
> Aside from Ian’s typo comment, which could be fixed on application.
> 
> Acked-by: Darrell Ball <dlu998@gmail.com>
> 
> I tested a few scenarios to see if the numbers made sense.
> 
> 
> 
> On 5/26/17, 7:13 AM, "ovs-dev-bounces@openvswitch.org on behalf of Stokes, Ian" <ovs-dev-bounces@openvswitch.org on behalf of ian.stokes@intel.com> wrote:
> 
>     > Instead of counting all polling cycles as processing cycles, only count
>     > the cycles where packets were received from the polling.
>     > 
>     > Signed-off-by: Georg Schmuecking <georg.schmuecking@ericsson.com>
>     > Signed-off-by: Ciara Loftus <ciara.loftus@intel.com>
>     > Co-authored-by: Georg Schmuecking <georg.schmuecking@ericsson.com>
>     > Acked-by: Kevin Traynor <ktraynor@redhat.com>
>     > ---
>     > v4:
>     > - Move call to cycles_count_intermediate in order to collect more
>     >   accurate statistics.
>     > v3:
>     > - Updated acks & co-author tags
>     > - Removed unnecessary PMD_CYCLES_POLLING counter type
>     > - Explain terms 'idle' and 'processing' cycles in
>     >   vswitchd/ovs-vswitchd.8.in
>     > v2:
>     > - Rebase
>     > 
>     >  lib/dpif-netdev.c          | 58 +++++++++++++++++++++++++++++++++++------
>     > -----
>     >  vswitchd/ovs-vswitchd.8.in |  5 +++-
>     >  2 files changed, 48 insertions(+), 15 deletions(-)
>     > 
>     > diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 30907b7..a80ffb2
>     > 100644
>     > --- a/lib/dpif-netdev.c
>     > +++ b/lib/dpif-netdev.c
>     > @@ -279,8 +279,9 @@ enum dp_stat_type {
>     >  };
>     > 
>     >  enum pmd_cycles_counter_type {
>     > -    PMD_CYCLES_POLLING,         /* Cycles spent polling NICs. */
>     > -    PMD_CYCLES_PROCESSING,      /* Cycles spent processing packets */
>     > +    PMD_CYCLES_IDLE,            /* Cycles spent idle or unsuccessful
>     > polling */
>     > +    PMD_CYCLES_PROCESSING,      /* Cycles spent successfully polling and
>     > +                                 * processing polled packets */
>     >      PMD_N_CYCLES
>     >  };
>     > 
>     > @@ -755,10 +756,10 @@ pmd_info_show_stats(struct ds *reply,
>     >      }
>     > 
>     >      ds_put_format(reply,
>     > -                  "\tpolling cycles:%"PRIu64" (%.02f%%)\n"
>     > +                  "\tidle cycles:%"PRIu64" (%.02f%%)\n"
>     >                    "\tprocessing cycles:%"PRIu64" (%.02f%%)\n",
>     > -                  cycles[PMD_CYCLES_POLLING],
>     > -                  cycles[PMD_CYCLES_POLLING] / (double)total_cycles *
>     > 100,
>     > +                  cycles[PMD_CYCLES_IDLE],
>     > +                  cycles[PMD_CYCLES_IDLE] / (double)total_cycles * 100,
>     >                    cycles[PMD_CYCLES_PROCESSING],
>     >                    cycles[PMD_CYCLES_PROCESSING] / (double)total_cycles *
>     > 100);
>     > 
>     > @@ -2953,30 +2954,43 @@ cycles_count_end(struct dp_netdev_pmd_thread *pmd,
>     >      non_atomic_ullong_add(&pmd->cycles.n[type], interval);  }
>     > 
>     > -static void
>     > +/* Calculate the intermediate cycle result and add to the counter
>     > +'type' */ static inline void cycles_count_intermediate(struct
>     > +dp_netdev_pmd_thread *pmd,
>     > +                          enum pmd_cycles_counter_type type)
>     > +    OVS_NO_THREAD_SAFETY_ANALYSIS
>     > +{
>     > +    unsigned long long new_cycles = cycles_counter();
>     > +    unsigned long long interval = new_cycles - pmd->last_cycles;
>     > +    pmd->last_cycles = new_cycles;
>     > +
>     > +    non_atomic_ullong_add(&pmd->cycles.n[type], interval); }
>     > +
>     > +static int
>     >  dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
>     >                             struct netdev_rxq *rx,
>     >                             odp_port_t port_no)  {
>     >      struct dp_packet_batch batch;
>     >      int error;
>     > +    int batch_cnt = 0;
>     > 
>     >      dp_packet_batch_init(&batch);
>     > -    cycles_count_start(pmd);
>     >      error = netdev_rxq_recv(rx, &batch);
>     > -    cycles_count_end(pmd, PMD_CYCLES_POLLING);
>     >      if (!error) {
>     >          *recirc_depth_get() = 0;
>     > 
>     > -        cycles_count_start(pmd);
>     > +        batch_cnt = batch.count;
>     >          dp_netdev_input(pmd, &batch, port_no);
>     > -        cycles_count_end(pmd, PMD_CYCLES_PROCESSING);
>     >      } else if (error != EAGAIN && error != EOPNOTSUPP) {
>     >          static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>     > 
>     >          VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
>     >                      netdev_rxq_get_name(rx), ovs_strerror(error));
>     >      }
>     > +
>     > +    return batch_cnt;
>     >  }
>     > 
>     >  static struct tx_port *
>     > @@ -3438,21 +3452,29 @@ dpif_netdev_run(struct dpif *dpif)
>     >      struct dp_netdev *dp = get_dp_netdev(dpif);
>     >      struct dp_netdev_pmd_thread *non_pmd;
>     >      uint64_t new_tnl_seq;
>     > +    int process_packets = 0;
>     > 
>     >      ovs_mutex_lock(&dp->port_mutex);
>     >      non_pmd = dp_netdev_get_pmd(dp, NON_PMD_CORE_ID);
>     >      if (non_pmd) {
>     >          ovs_mutex_lock(&dp->non_pmd_mutex);
>     > +        cycles_count_start(non_pmd);
>     >          HMAP_FOR_EACH (port, node, &dp->ports) {
>     >              if (!netdev_is_pmd(port->netdev)) {
>     >                  int i;
>     > 
>     >                  for (i = 0; i < port->n_rxq; i++) {
>     > -                    dp_netdev_process_rxq_port(non_pmd, port->rxqs[i].rx,
>     > -                                               port->port_no);
>     > +                    process_packets =
>     > +                        dp_netdev_process_rxq_port(non_pmd,
>     > +                                                   port->rxqs[i].rx,
>     > +                                                   port->port_no);
>     > +                    cycles_count_intermediate(non_pmd, process_packets ?
>     > +
>     > PMD_CYCLES_PROCESSING
>     > +                                                     :
>     > + PMD_CYCLES_IDLE);
>     >                  }
>     >              }
>     >          }
>     > +        cycles_count_end(non_pmd, PMD_CYCLES_IDLE);
>     >          dpif_netdev_xps_revalidate_pmd(non_pmd, time_msec(), false);
>     >          ovs_mutex_unlock(&dp->non_pmd_mutex);
>     > 
>     > @@ -3577,6 +3599,7 @@ pmd_thread_main(void *f_)
>     >      bool exiting;
>     >      int poll_cnt;
>     >      int i;
>     > +    int process_packets = 0;
>     > 
>     >      poll_list = NULL;
>     > 
>     > @@ -3603,10 +3626,15 @@ reload:
>     >          lc = UINT_MAX;
>     >      }
>     > 
>     > +    cycles_count_start(pmd);
>     >      for (;;) {
>     >          for (i = 0; i < poll_cnt; i++) {
>     > -            dp_netdev_process_rxq_port(pmd, poll_list[i].rx,
>     > -                                       poll_list[i].port_no);
>     > +            process_packets =
>     > +                dp_netdev_process_rxq_port(pmd, poll_list[i].rx,
>     > +                                           poll_list[i].port_no);
>     > +            cycles_count_intermediate(pmd,
>     > +                                      process_packets ?
>     > PMD_CYCLES_PROCESSING
>     > +                                                      :
>     > + PMD_CYCLES_IDLE);
>     >          }
>     > 
>     >          if (lc++ > 1024) {
>     > @@ -3627,6 +3655,8 @@ reload:
>     >          }
>     >      }
>     > 
>     > +    cycles_count_end(pmd, PMD_CYCLES_IDLE);
>     > +
>     >      poll_cnt = pmd_load_queues_and_ports(pmd, &poll_list);
>     >      exiting = latch_is_set(&pmd->exit_latch);
>     >      /* Signal here to make sure the pmd finishes diff --git
>     > a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index
>     > fc19f3b..2e6e684 100644
>     > --- a/vswitchd/ovs-vswitchd.8.in
>     > +++ b/vswitchd/ovs-vswitchd.8.in
>     > @@ -253,7 +253,10 @@ The sum of ``emc hits'', ``masked hits'' and ``miss''
>     > is the number of  packets received by the datapath.  Cycles are counted
>     > using the TSC or similar  facilities (when available on the platform).  To
>     > reset these counters use  \fBdpif-netdev/pmd-stats-clear\fR. The duration
>     > of one cycle depends on the -measuring infrastructure.
>     > +measuring infrastructure. ``idle cycles'' refers to cycles spent
>     > +polling devices but not receiving any packets. ``processing cycles''
>     > +refers to cycles spent polling devices and sucessfully receiving
>     
>     Typo above in 'sucessfully'
>     
>     > +packets, plus the cycles spent processing said packets.
>     >  .IP "\fBdpif-netdev/pmd-stats-clear\fR [\fIdp\fR]"
>     >  Resets to zero the per pmd thread performance numbers shown by the
>     > \fBdpif-netdev/pmd-stats-show\fR command.  It will NOT reset datapath or
>     > --
>     
>     Other than that LGTM. I've tested behavior and verified compilation with gcc, clang and sparse.
>     
>     Acked-by: Ian Stokes <ian.stokes@intel.com>
>     Tested-by: Ian Stokes <ian.stokes@intel.com>
>     _______________________________________________
>     dev mailing list
>     dev@openvswitch.org
>     https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.openvswitch.org_mailman_listinfo_ovs-2Ddev&d=DwICAg&c=uilaK90D4TOVoH58JNXRgQ&r=BVhFA09CGX7JQ5Ih-uZnsw&m=qsZ_NICrLITF6gtbrgjmBHvJDaCKMm8iJJsPyW8cYvE&s=p6LdM8QboVckrfzxHNVr7iB8aA7PMyY_1QJCibU-I-I&e= 
>     
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff mbox

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 30907b7..a80ffb2 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -279,8 +279,9 @@  enum dp_stat_type {
 };
 
 enum pmd_cycles_counter_type {
-    PMD_CYCLES_POLLING,         /* Cycles spent polling NICs. */
-    PMD_CYCLES_PROCESSING,      /* Cycles spent processing packets */
+    PMD_CYCLES_IDLE,            /* Cycles spent idle or unsuccessful polling */
+    PMD_CYCLES_PROCESSING,      /* Cycles spent successfully polling and
+                                 * processing polled packets */
     PMD_N_CYCLES
 };
 
@@ -755,10 +756,10 @@  pmd_info_show_stats(struct ds *reply,
     }
 
     ds_put_format(reply,
-                  "\tpolling cycles:%"PRIu64" (%.02f%%)\n"
+                  "\tidle cycles:%"PRIu64" (%.02f%%)\n"
                   "\tprocessing cycles:%"PRIu64" (%.02f%%)\n",
-                  cycles[PMD_CYCLES_POLLING],
-                  cycles[PMD_CYCLES_POLLING] / (double)total_cycles * 100,
+                  cycles[PMD_CYCLES_IDLE],
+                  cycles[PMD_CYCLES_IDLE] / (double)total_cycles * 100,
                   cycles[PMD_CYCLES_PROCESSING],
                   cycles[PMD_CYCLES_PROCESSING] / (double)total_cycles * 100);
 
@@ -2953,30 +2954,43 @@  cycles_count_end(struct dp_netdev_pmd_thread *pmd,
     non_atomic_ullong_add(&pmd->cycles.n[type], interval);
 }
 
-static void
+/* Calculate the intermediate cycle result and add to the counter 'type' */
+static inline void
+cycles_count_intermediate(struct dp_netdev_pmd_thread *pmd,
+                          enum pmd_cycles_counter_type type)
+    OVS_NO_THREAD_SAFETY_ANALYSIS
+{
+    unsigned long long new_cycles = cycles_counter();
+    unsigned long long interval = new_cycles - pmd->last_cycles;
+    pmd->last_cycles = new_cycles;
+
+    non_atomic_ullong_add(&pmd->cycles.n[type], interval);
+}
+
+static int
 dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
                            struct netdev_rxq *rx,
                            odp_port_t port_no)
 {
     struct dp_packet_batch batch;
     int error;
+    int batch_cnt = 0;
 
     dp_packet_batch_init(&batch);
-    cycles_count_start(pmd);
     error = netdev_rxq_recv(rx, &batch);
-    cycles_count_end(pmd, PMD_CYCLES_POLLING);
     if (!error) {
         *recirc_depth_get() = 0;
 
-        cycles_count_start(pmd);
+        batch_cnt = batch.count;
         dp_netdev_input(pmd, &batch, port_no);
-        cycles_count_end(pmd, PMD_CYCLES_PROCESSING);
     } else if (error != EAGAIN && error != EOPNOTSUPP) {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
         VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
                     netdev_rxq_get_name(rx), ovs_strerror(error));
     }
+
+    return batch_cnt;
 }
 
 static struct tx_port *
@@ -3438,21 +3452,29 @@  dpif_netdev_run(struct dpif *dpif)
     struct dp_netdev *dp = get_dp_netdev(dpif);
     struct dp_netdev_pmd_thread *non_pmd;
     uint64_t new_tnl_seq;
+    int process_packets = 0;
 
     ovs_mutex_lock(&dp->port_mutex);
     non_pmd = dp_netdev_get_pmd(dp, NON_PMD_CORE_ID);
     if (non_pmd) {
         ovs_mutex_lock(&dp->non_pmd_mutex);
+        cycles_count_start(non_pmd);
         HMAP_FOR_EACH (port, node, &dp->ports) {
             if (!netdev_is_pmd(port->netdev)) {
                 int i;
 
                 for (i = 0; i < port->n_rxq; i++) {
-                    dp_netdev_process_rxq_port(non_pmd, port->rxqs[i].rx,
-                                               port->port_no);
+                    process_packets =
+                        dp_netdev_process_rxq_port(non_pmd,
+                                                   port->rxqs[i].rx,
+                                                   port->port_no);
+                    cycles_count_intermediate(non_pmd, process_packets ?
+                                                       PMD_CYCLES_PROCESSING
+                                                     : PMD_CYCLES_IDLE);
                 }
             }
         }
+        cycles_count_end(non_pmd, PMD_CYCLES_IDLE);
         dpif_netdev_xps_revalidate_pmd(non_pmd, time_msec(), false);
         ovs_mutex_unlock(&dp->non_pmd_mutex);
 
@@ -3577,6 +3599,7 @@  pmd_thread_main(void *f_)
     bool exiting;
     int poll_cnt;
     int i;
+    int process_packets = 0;
 
     poll_list = NULL;
 
@@ -3603,10 +3626,15 @@  reload:
         lc = UINT_MAX;
     }
 
+    cycles_count_start(pmd);
     for (;;) {
         for (i = 0; i < poll_cnt; i++) {
-            dp_netdev_process_rxq_port(pmd, poll_list[i].rx,
-                                       poll_list[i].port_no);
+            process_packets =
+                dp_netdev_process_rxq_port(pmd, poll_list[i].rx,
+                                           poll_list[i].port_no);
+            cycles_count_intermediate(pmd,
+                                      process_packets ? PMD_CYCLES_PROCESSING
+                                                      : PMD_CYCLES_IDLE);
         }
 
         if (lc++ > 1024) {
@@ -3627,6 +3655,8 @@  reload:
         }
     }
 
+    cycles_count_end(pmd, PMD_CYCLES_IDLE);
+
     poll_cnt = pmd_load_queues_and_ports(pmd, &poll_list);
     exiting = latch_is_set(&pmd->exit_latch);
     /* Signal here to make sure the pmd finishes
diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
index fc19f3b..2e6e684 100644
--- a/vswitchd/ovs-vswitchd.8.in
+++ b/vswitchd/ovs-vswitchd.8.in
@@ -253,7 +253,10 @@  The sum of ``emc hits'', ``masked hits'' and ``miss'' is the number of
 packets received by the datapath.  Cycles are counted using the TSC or similar
 facilities (when available on the platform).  To reset these counters use
 \fBdpif-netdev/pmd-stats-clear\fR. The duration of one cycle depends on the
-measuring infrastructure.
+measuring infrastructure. ``idle cycles'' refers to cycles spent polling
+devices but not receiving any packets. ``processing cycles'' refers to cycles
+spent polling devices and sucessfully receiving packets, plus the cycles
+spent processing said packets.
 .IP "\fBdpif-netdev/pmd-stats-clear\fR [\fIdp\fR]"
 Resets to zero the per pmd thread performance numbers shown by the
 \fBdpif-netdev/pmd-stats-show\fR command.  It will NOT reset datapath or