mirror of
https://github.com/openvswitch/ovs
synced 2025-10-13 14:07:02 +00:00
datapath: Drop queue information from odp_stats.
This queue information will be available through the kernel socket layer once we move over to Netlink socket as transports, so we might as well get rid of the redundancy. Signed-off-by: Ben Pfaff <blp@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
@@ -1222,8 +1222,6 @@ static int get_dp_stats(struct datapath *dp, struct odp_stats __user *statsp)
|
|||||||
stats.n_missed += local_stats.n_missed;
|
stats.n_missed += local_stats.n_missed;
|
||||||
stats.n_lost += local_stats.n_lost;
|
stats.n_lost += local_stats.n_lost;
|
||||||
}
|
}
|
||||||
stats.max_miss_queue = DP_MAX_QUEUE_LEN;
|
|
||||||
stats.max_action_queue = DP_MAX_QUEUE_LEN;
|
|
||||||
return copy_to_user(statsp, &stats, sizeof(stats)) ? -EFAULT : 0;
|
return copy_to_user(statsp, &stats, sizeof(stats)) ? -EFAULT : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -109,11 +109,6 @@ struct odp_stats {
|
|||||||
uint64_t n_hit; /* Number of flow table matches. */
|
uint64_t n_hit; /* Number of flow table matches. */
|
||||||
uint64_t n_missed; /* Number of flow table misses. */
|
uint64_t n_missed; /* Number of flow table misses. */
|
||||||
uint64_t n_lost; /* Number of misses not sent to userspace. */
|
uint64_t n_lost; /* Number of misses not sent to userspace. */
|
||||||
|
|
||||||
/* Queues. */
|
|
||||||
uint16_t max_miss_queue; /* Max length of ODPL_MISS queue. */
|
|
||||||
uint16_t max_action_queue; /* Max length of ODPL_ACTION queue. */
|
|
||||||
uint16_t max_sflow_queue; /* Max length of ODPL_SFLOW queue. */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Logical ports. */
|
/* Logical ports. */
|
||||||
|
@@ -645,6 +645,26 @@ dpif_linux_recv_wait(struct dpif *dpif_)
|
|||||||
poll_fd_wait(dpif->fd, POLLIN);
|
poll_fd_wait(dpif->fd, POLLIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dpif_linux_recv_purge(struct dpif *dpif_)
|
||||||
|
{
|
||||||
|
struct dpif_linux *dpif = dpif_linux_cast(dpif_);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* This is somewhat bogus because it assumes that the following macros have
|
||||||
|
* fixed values, but it's going to go away later. */
|
||||||
|
#define DP_N_QUEUES 3
|
||||||
|
#define DP_MAX_QUEUE_LEN 100
|
||||||
|
for (i = 0; i < DP_N_QUEUES * DP_MAX_QUEUE_LEN; i++) {
|
||||||
|
/* Reading even 1 byte discards a whole datagram and saves time. */
|
||||||
|
char buffer;
|
||||||
|
|
||||||
|
if (read(dpif->fd, &buffer, 1) != 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const struct dpif_class dpif_linux_class = {
|
const struct dpif_class dpif_linux_class = {
|
||||||
"system",
|
"system",
|
||||||
NULL,
|
NULL,
|
||||||
@@ -681,6 +701,7 @@ const struct dpif_class dpif_linux_class = {
|
|||||||
dpif_linux_queue_to_priority,
|
dpif_linux_queue_to_priority,
|
||||||
dpif_linux_recv,
|
dpif_linux_recv,
|
||||||
dpif_linux_recv_wait,
|
dpif_linux_recv_wait,
|
||||||
|
dpif_linux_recv_purge,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int get_openvswitch_major(void);
|
static int get_openvswitch_major(void);
|
||||||
|
@@ -246,27 +246,32 @@ dpif_netdev_open(const struct dpif_class *class, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dp_netdev_free(struct dp_netdev *dp)
|
dp_netdev_purge_queues(struct dp_netdev *dp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < N_QUEUES; i++) {
|
||||||
|
struct dp_netdev_queue *q = &dp->queues[i];
|
||||||
|
|
||||||
|
while (q->tail != q->head) {
|
||||||
|
struct dpif_upcall *upcall = q->upcalls[q->tail++ & QUEUE_MASK];
|
||||||
|
|
||||||
|
ofpbuf_delete(upcall->packet);
|
||||||
|
free(upcall);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dp_netdev_free(struct dp_netdev *dp)
|
||||||
|
{
|
||||||
dp_netdev_flow_flush(dp);
|
dp_netdev_flow_flush(dp);
|
||||||
while (dp->n_ports > 0) {
|
while (dp->n_ports > 0) {
|
||||||
struct dp_netdev_port *port = CONTAINER_OF(
|
struct dp_netdev_port *port = CONTAINER_OF(
|
||||||
dp->port_list.next, struct dp_netdev_port, node);
|
dp->port_list.next, struct dp_netdev_port, node);
|
||||||
do_del_port(dp, port->port_no);
|
do_del_port(dp, port->port_no);
|
||||||
}
|
}
|
||||||
for (i = 0; i < N_QUEUES; i++) {
|
dp_netdev_purge_queues(dp);
|
||||||
struct dp_netdev_queue *q = &dp->queues[i];
|
|
||||||
unsigned int j;
|
|
||||||
|
|
||||||
for (j = q->tail; j != q->head; j++) {
|
|
||||||
struct dpif_upcall *upcall = q->upcalls[j & QUEUE_MASK];
|
|
||||||
|
|
||||||
ofpbuf_delete(upcall->packet);
|
|
||||||
free(upcall);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hmap_destroy(&dp->flow_table);
|
hmap_destroy(&dp->flow_table);
|
||||||
free(dp->name);
|
free(dp->name);
|
||||||
free(dp);
|
free(dp);
|
||||||
@@ -303,8 +308,6 @@ dpif_netdev_get_stats(const struct dpif *dpif, struct odp_stats *stats)
|
|||||||
stats->n_hit = dp->n_hit;
|
stats->n_hit = dp->n_hit;
|
||||||
stats->n_missed = dp->n_missed;
|
stats->n_missed = dp->n_missed;
|
||||||
stats->n_lost = dp->n_lost;
|
stats->n_lost = dp->n_lost;
|
||||||
stats->max_miss_queue = MAX_QUEUE_LEN;
|
|
||||||
stats->max_action_queue = MAX_QUEUE_LEN;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1011,6 +1014,13 @@ dpif_netdev_recv_wait(struct dpif *dpif)
|
|||||||
* wake up to queue new messages, so there is nothing to do. */
|
* wake up to queue new messages, so there is nothing to do. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dpif_netdev_recv_purge(struct dpif *dpif)
|
||||||
|
{
|
||||||
|
struct dpif_netdev *dpif_netdev = dpif_netdev_cast(dpif);
|
||||||
|
dp_netdev_purge_queues(dpif_netdev->dp);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dp_netdev_flow_used(struct dp_netdev_flow *flow, struct flow *key,
|
dp_netdev_flow_used(struct dp_netdev_flow *flow, struct flow *key,
|
||||||
@@ -1403,6 +1413,7 @@ const struct dpif_class dpif_netdev_class = {
|
|||||||
NULL, /* queue_to_priority */
|
NULL, /* queue_to_priority */
|
||||||
dpif_netdev_recv,
|
dpif_netdev_recv,
|
||||||
dpif_netdev_recv_wait,
|
dpif_netdev_recv_wait,
|
||||||
|
dpif_netdev_recv_purge,
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010 Nicira Networks.
|
* Copyright (c) 2009, 2010, 2011 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -348,6 +348,10 @@ struct dpif_class {
|
|||||||
/* Arranges for the poll loop to wake up when 'dpif' has a message queued
|
/* Arranges for the poll loop to wake up when 'dpif' has a message queued
|
||||||
* to be received with the recv member function. */
|
* to be received with the recv member function. */
|
||||||
void (*recv_wait)(struct dpif *dpif);
|
void (*recv_wait)(struct dpif *dpif);
|
||||||
|
|
||||||
|
/* Throws away any queued upcalls that 'dpif' currently has ready to
|
||||||
|
* return. */
|
||||||
|
void (*recv_purge)(struct dpif *dpif);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct dpif_class dpif_linux_class;
|
extern const struct dpif_class dpif_linux_class;
|
||||||
|
24
lib/dpif.c
24
lib/dpif.c
@@ -1030,30 +1030,14 @@ dpif_recv(struct dpif *dpif, struct dpif_upcall *upcall)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Discards all messages that would otherwise be received by dpif_recv() on
|
/* Discards all messages that would otherwise be received by dpif_recv() on
|
||||||
* 'dpif'. Returns 0 if successful, otherwise a positive errno value. */
|
* 'dpif'. */
|
||||||
int
|
void
|
||||||
dpif_recv_purge(struct dpif *dpif)
|
dpif_recv_purge(struct dpif *dpif)
|
||||||
{
|
{
|
||||||
struct odp_stats stats;
|
|
||||||
unsigned int i;
|
|
||||||
int error;
|
|
||||||
|
|
||||||
COVERAGE_INC(dpif_purge);
|
COVERAGE_INC(dpif_purge);
|
||||||
|
if (dpif->dpif_class->recv_purge) {
|
||||||
error = dpif_get_dp_stats(dpif, &stats);
|
dpif->dpif_class->recv_purge(dpif);
|
||||||
if (error) {
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < stats.max_miss_queue + stats.max_action_queue + stats.max_sflow_queue; i++) {
|
|
||||||
struct dpif_upcall upcall;
|
|
||||||
error = dpif_recv(dpif, &upcall);
|
|
||||||
if (error) {
|
|
||||||
return error == EAGAIN ? 0 : error;
|
|
||||||
}
|
|
||||||
ofpbuf_delete(upcall.packet);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Arranges for the poll loop to wake up when 'dpif' has a message queued to be
|
/* Arranges for the poll loop to wake up when 'dpif' has a message queued to be
|
||||||
|
@@ -153,7 +153,7 @@ int dpif_recv_set_mask(struct dpif *, int listen_mask);
|
|||||||
int dpif_get_sflow_probability(const struct dpif *, uint32_t *probability);
|
int dpif_get_sflow_probability(const struct dpif *, uint32_t *probability);
|
||||||
int dpif_set_sflow_probability(struct dpif *, uint32_t probability);
|
int dpif_set_sflow_probability(struct dpif *, uint32_t probability);
|
||||||
int dpif_recv(struct dpif *, struct dpif_upcall *);
|
int dpif_recv(struct dpif *, struct dpif_upcall *);
|
||||||
int dpif_recv_purge(struct dpif *);
|
void dpif_recv_purge(struct dpif *);
|
||||||
void dpif_recv_wait(struct dpif *);
|
void dpif_recv_wait(struct dpif *);
|
||||||
|
|
||||||
void dpif_get_netflow_ids(const struct dpif *,
|
void dpif_get_netflow_ids(const struct dpif *,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008, 2009, 2010 Nicira Networks.
|
* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -345,8 +345,6 @@ show_dpif(struct dpif *dpif)
|
|||||||
(unsigned long long int) stats.n_hit,
|
(unsigned long long int) stats.n_hit,
|
||||||
(unsigned long long int) stats.n_missed,
|
(unsigned long long int) stats.n_missed,
|
||||||
(unsigned long long int) stats.n_lost);
|
(unsigned long long int) stats.n_lost);
|
||||||
printf("\tqueues: max-miss:%"PRIu16", max-action:%"PRIu16"\n",
|
|
||||||
stats.max_miss_queue, stats.max_action_queue);
|
|
||||||
}
|
}
|
||||||
DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) {
|
DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) {
|
||||||
printf("\tport %u: %s", dpif_port.port_no, dpif_port.name);
|
printf("\tport %u: %s", dpif_port.port_no, dpif_port.name);
|
||||||
|
Reference in New Issue
Block a user