datapath: Drop queue information from odp_stats.
authorBen Pfaff <blp@nicira.com>
Wed, 5 Jan 2011 01:00:36 +0000 (17:00 -0800)
committerBen Pfaff <blp@nicira.com>
Fri, 28 Jan 2011 05:08:38 +0000 (21:08 -0800)
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>
datapath/datapath.c
include/openvswitch/datapath-protocol.h
lib/dpif-linux.c
lib/dpif-netdev.c
lib/dpif-provider.h
lib/dpif.c
lib/dpif.h
utilities/ovs-dpctl.c

index 3d32cd47ae9b6d1f4cae7ac43fcaabe76e64d72a..3cc336695f7ba5f25000f59a733b4b01d1c02485 100644 (file)
@@ -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_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;
 }
 
index 36f1bc160e02de0b9320064d04fcd9efa92ee754..d744b9f4d08587cb4e3dd10115d4a81f825ddf4b 100644 (file)
@@ -109,11 +109,6 @@ struct odp_stats {
     uint64_t n_hit;             /* Number of flow table matches. */
     uint64_t n_missed;          /* Number of flow table misses. */
     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. */
index 8e584ea5de051a012a823994495ba7ff1a67c3a8..e5ea31a5e8099a910750a70d891bc01077ed9d6c 100644 (file)
@@ -645,6 +645,26 @@ dpif_linux_recv_wait(struct dpif *dpif_)
     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 = {
     "system",
     NULL,
@@ -681,6 +701,7 @@ const struct dpif_class dpif_linux_class = {
     dpif_linux_queue_to_priority,
     dpif_linux_recv,
     dpif_linux_recv_wait,
+    dpif_linux_recv_purge,
 };
 \f
 static int get_openvswitch_major(void);
index d17b82b69cf7a3ec006af0cc2bd109d8dbc8c117..8a0363c948dba7f66423aa3dd30b836c05fd536f 100644 (file)
@@ -246,27 +246,32 @@ dpif_netdev_open(const struct dpif_class *class, const char *name,
 }
 
 static void
-dp_netdev_free(struct dp_netdev *dp)
+dp_netdev_purge_queues(struct dp_netdev *dp)
 {
     int i;
 
-    dp_netdev_flow_flush(dp);
-    while (dp->n_ports > 0) {
-        struct dp_netdev_port *port = CONTAINER_OF(
-            dp->port_list.next, struct dp_netdev_port, node);
-        do_del_port(dp, port->port_no);
-    }
     for (i = 0; i < N_QUEUES; i++) {
         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];
+        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);
+    while (dp->n_ports > 0) {
+        struct dp_netdev_port *port = CONTAINER_OF(
+            dp->port_list.next, struct dp_netdev_port, node);
+        do_del_port(dp, port->port_no);
+    }
+    dp_netdev_purge_queues(dp);
     hmap_destroy(&dp->flow_table);
     free(dp->name);
     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_missed = dp->n_missed;
     stats->n_lost = dp->n_lost;
-    stats->max_miss_queue = MAX_QUEUE_LEN;
-    stats->max_action_queue = MAX_QUEUE_LEN;
     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. */
     }
 }
+
+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);
+}
 \f
 static void
 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 */
     dpif_netdev_recv,
     dpif_netdev_recv_wait,
+    dpif_netdev_recv_purge,
 };
 
 void
index f138104fa7d38fa832976cace661060c99e42eb3..eca005981c5c05888250e40c5a2e1536b3d8888a 100644 (file)
@@ -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");
  * 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
      * to be received with the recv member function. */
     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;
index 1fff27f9003250ca0e2780f7eb72d57924f740c7..a4dcf4b4883af5deb248adc8a5c7218ac7ad6b43 100644 (file)
@@ -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
- * 'dpif'.  Returns 0 if successful, otherwise a positive errno value. */
-int
+ * 'dpif'. */
+void
 dpif_recv_purge(struct dpif *dpif)
 {
-    struct odp_stats stats;
-    unsigned int i;
-    int error;
-
     COVERAGE_INC(dpif_purge);
-
-    error = dpif_get_dp_stats(dpif, &stats);
-    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);
+    if (dpif->dpif_class->recv_purge) {
+        dpif->dpif_class->recv_purge(dpif);
     }
-    return 0;
 }
 
 /* Arranges for the poll loop to wake up when 'dpif' has a message queued to be
index 3c6915d00c99ff656fb848ced16e39da29e26927..c51071da6a6f8ff973c6f58c0def9deab35f9765 100644 (file)
@@ -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_set_sflow_probability(struct dpif *, uint32_t probability);
 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_get_netflow_ids(const struct dpif *,
index 2e2197ed5e999e6dd4d9184b21132563fc6a0fa7..12500805f22b6657bce4af029516c583a708315f 100644 (file)
@@ -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");
  * 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_missed,
                (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) {
         printf("\tport %u: %s", dpif_port.port_no, dpif_port.name);