[ovs-dev] [PATCH v2 1/7] dp-packet: Remove 'list' member.

Daniele Di Proietto diproiettod at vmware.com
Mon May 18 17:47:45 UTC 2015


The 'list' member is only used (two users) in the slow path.
This commit removes it to reduce the struct size

Signed-off-by: Daniele Di Proietto <diproiettod at vmware.com>
---
 lib/dp-packet.c        | 13 -------------
 lib/dp-packet.h        |  8 --------
 lib/netdev-dummy.c     | 48 ++++++++++++++++++++++++++++++++++++++++--------
 ofproto/ofproto-dpif.c | 30 ++++++++++++++----------------
 4 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/lib/dp-packet.c b/lib/dp-packet.c
index 8a4cf43..b2d9d5c 100644
--- a/lib/dp-packet.c
+++ b/lib/dp-packet.c
@@ -31,7 +31,6 @@ dp_packet_init__(struct dp_packet *b, size_t allocated, enum dp_packet_source so
     b->l2_pad_size = 0;
     b->l2_5_ofs = b->l3_ofs = b->l4_ofs = UINT16_MAX;
     b->md = PKT_METADATA_INITIALIZER(0);
-    list_poison(&b->list_node);
 }
 
 static void
@@ -460,18 +459,6 @@ dp_packet_to_string(const struct dp_packet *b, size_t maxbytes)
     return ds_cstr(&s);
 }
 
-/* Removes each of the "struct dp_packet"s on 'list' from the list and frees
- * them.  */
-void
-dp_packet_list_delete(struct ovs_list *list)
-{
-    struct dp_packet *b;
-
-    LIST_FOR_EACH_POP (b, list_node, list) {
-        dp_packet_delete(b);
-    }
-}
-
 static inline void
 dp_packet_adjust_layer_offset(uint16_t *offset, int increment)
 {
diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index fd23d11..29a883b 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -78,7 +78,6 @@ struct dp_packet {
     uint16_t l4_ofs;            /* Transport-level header offset from 'frame',
                                    or UINT16_MAX. */
     struct pkt_metadata md;
-    struct ovs_list list_node;  /* Private list element for use by owner. */
 };
 
 static inline void * dp_packet_data(const struct dp_packet *);
@@ -159,8 +158,6 @@ static inline void *dp_packet_try_pull(struct dp_packet *, size_t);
 void *dp_packet_steal_data(struct dp_packet *);
 
 char *dp_packet_to_string(const struct dp_packet *, size_t maxbytes);
-static inline struct dp_packet *dp_packet_from_list(const struct ovs_list *);
-void dp_packet_list_delete(struct ovs_list *);
 static inline bool dp_packet_equal(const struct dp_packet *, const struct dp_packet *);
 
 
@@ -262,11 +259,6 @@ static inline void *dp_packet_try_pull(struct dp_packet *b, size_t size)
         ? dp_packet_pull(b, size) : NULL;
 }
 
-static inline struct dp_packet *dp_packet_from_list(const struct ovs_list *list)
-{
-    return CONTAINER_OF(list, struct dp_packet, list_node);
-}
-
 static inline bool dp_packet_equal(const struct dp_packet *a, const struct dp_packet *b)
 {
     return dp_packet_size(a) == dp_packet_size(b) &&
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 64f8f66..33d0876 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -84,6 +84,11 @@ struct dummy_packet_conn {
     } u;
 };
 
+struct pkt_list_node {
+    struct dp_packet *pkt;
+    struct ovs_list list_node;
+};
+
 /* Protects 'dummy_list'. */
 static struct ovs_mutex dummy_list_mutex = OVS_MUTEX_INITIALIZER;
 
@@ -131,6 +136,8 @@ static void netdev_dummy_queue_packet(struct netdev_dummy *, struct dp_packet *)
 
 static void dummy_packet_stream_close(struct dummy_packet_stream *);
 
+static void pkt_list_delete(struct ovs_list *);
+
 static bool
 is_dummy_class(const struct netdev_class *class)
 {
@@ -186,10 +193,14 @@ dummy_packet_stream_send(struct dummy_packet_stream *s, const void *buffer, size
 {
     if (list_size(&s->txq) < NETDEV_DUMMY_MAX_QUEUE) {
         struct dp_packet *b;
+        struct pkt_list_node *node;
 
         b = dp_packet_clone_data_with_headroom(buffer, size, 2);
         put_unaligned_be16(dp_packet_push_uninit(b, 2), htons(size));
-        list_push_back(&s->txq, &b->list_node);
+
+        node = xmalloc(sizeof *node);
+        node->pkt = b;
+        list_push_back(&s->txq, &node->list_node);
     }
 }
 
@@ -202,16 +213,19 @@ dummy_packet_stream_run(struct netdev_dummy *dev, struct dummy_packet_stream *s)
     stream_run(s->stream);
 
     if (!list_is_empty(&s->txq)) {
+        struct pkt_list_node *txbuf_node;
         struct dp_packet *txbuf;
         int retval;
 
-        txbuf = dp_packet_from_list(list_front(&s->txq));
+        ASSIGN_CONTAINER(txbuf_node, list_front(&s->txq), list_node);
+        txbuf = txbuf_node->pkt;
         retval = stream_send(s->stream, dp_packet_data(txbuf), dp_packet_size(txbuf));
 
         if (retval > 0) {
             dp_packet_pull(txbuf, retval);
             if (!dp_packet_size(txbuf)) {
-                list_remove(&txbuf->list_node);
+                list_remove(&txbuf_node->list_node);
+                free(txbuf_node);
                 dp_packet_delete(txbuf);
             }
         } else if (retval != -EAGAIN) {
@@ -263,7 +277,7 @@ dummy_packet_stream_close(struct dummy_packet_stream *s)
 {
     stream_close(s->stream);
     dp_packet_uninit(&s->rxbuf);
-    dp_packet_list_delete(&s->txq);
+    pkt_list_delete(&s->txq);
 }
 
 static void
@@ -797,7 +811,7 @@ netdev_dummy_rxq_destruct(struct netdev_rxq *rxq_)
 
     ovs_mutex_lock(&netdev->mutex);
     list_remove(&rx->node);
-    dp_packet_list_delete(&rx->recv_queue);
+    pkt_list_delete(&rx->recv_queue);
     ovs_mutex_unlock(&netdev->mutex);
     seq_destroy(rx->seq);
 }
@@ -820,7 +834,11 @@ netdev_dummy_rxq_recv(struct netdev_rxq *rxq_, struct dp_packet **arr,
 
     ovs_mutex_lock(&netdev->mutex);
     if (!list_is_empty(&rx->recv_queue)) {
-        packet = dp_packet_from_list(list_pop_front(&rx->recv_queue));
+        struct pkt_list_node *pkt_node;
+
+        ASSIGN_CONTAINER(pkt_node, list_pop_front(&rx->recv_queue), list_node);
+        packet = pkt_node->pkt;
+        free(pkt_node);
         rx->recv_queue_len--;
     } else {
         packet = NULL;
@@ -866,7 +884,7 @@ netdev_dummy_rxq_drain(struct netdev_rxq *rxq_)
     struct netdev_dummy *netdev = netdev_dummy_cast(rx->up.netdev);
 
     ovs_mutex_lock(&netdev->mutex);
-    dp_packet_list_delete(&rx->recv_queue);
+    pkt_list_delete(&rx->recv_queue);
     rx->recv_queue_len = 0;
     ovs_mutex_unlock(&netdev->mutex);
 
@@ -1116,6 +1134,17 @@ static const struct netdev_class dummy_class = {
     netdev_dummy_rxq_drain,
 };
 
+static void
+pkt_list_delete(struct ovs_list *l)
+{
+    struct pkt_list_node *pkt;
+
+    LIST_FOR_EACH_POP(pkt, list_node, l) {
+        dp_packet_delete(pkt->pkt);
+        free(pkt);
+    }
+}
+
 static struct dp_packet *
 eth_from_packet_or_flow(const char *s)
 {
@@ -1159,7 +1188,10 @@ eth_from_packet_or_flow(const char *s)
 static void
 netdev_dummy_queue_packet__(struct netdev_rxq_dummy *rx, struct dp_packet *packet)
 {
-    list_push_back(&rx->recv_queue, &packet->list_node);
+    struct pkt_list_node *pkt_node = xmalloc(sizeof *pkt_node);
+
+    pkt_node->pkt = packet;
+    list_push_back(&rx->recv_queue, &pkt_node->list_node);
     rx->recv_queue_len++;
     seq_change(rx->seq);
 }
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index bf89321..d151bb7 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -2974,43 +2974,41 @@ static void
 bundle_send_learning_packets(struct ofbundle *bundle)
 {
     struct ofproto_dpif *ofproto = bundle->ofproto;
-    struct dp_packet *learning_packet;
     int error, n_packets, n_errors;
     struct mac_entry *e;
+    struct pkt_list {
+        struct ovs_list list_node;
+        struct ofport_dpif *port;
+        struct dp_packet *pkt;
+    } *pkt_node;
     struct ovs_list packets;
 
     list_init(&packets);
     ovs_rwlock_rdlock(&ofproto->ml->rwlock);
     LIST_FOR_EACH (e, lru_node, &ofproto->ml->lrus) {
         if (mac_entry_get_port(ofproto->ml, e) != bundle) {
-            void *port_void;
-
-            learning_packet = bond_compose_learning_packet(bundle->bond,
-                                                           e->mac, e->vlan,
-                                                           &port_void);
-            /* Temporarily use 'frame' as a private pointer (see below). */
-            ovs_assert(learning_packet->frame == dp_packet_data(learning_packet));
-            learning_packet->frame = port_void;
-            list_push_back(&packets, &learning_packet->list_node);
+            pkt_node = xmalloc(sizeof *pkt_node);
+            pkt_node->pkt = bond_compose_learning_packet(bundle->bond,
+                                                         e->mac, e->vlan,
+                                                         (void **)&pkt_node->port);
+            list_push_back(&packets, &pkt_node->list_node);
         }
     }
     ovs_rwlock_unlock(&ofproto->ml->rwlock);
 
     error = n_packets = n_errors = 0;
-    LIST_FOR_EACH (learning_packet, list_node, &packets) {
+    LIST_FOR_EACH_POP (pkt_node, list_node, &packets) {
         int ret;
-        void *port_void = learning_packet->frame;
 
-        /* Restore 'frame'. */
-        learning_packet->frame = dp_packet_data(learning_packet);
-        ret = ofproto_dpif_send_packet(port_void, learning_packet);
+        ret = ofproto_dpif_send_packet(pkt_node->port, pkt_node->pkt);
+        dp_packet_delete(pkt_node->pkt);
+        free(pkt_node);
         if (ret) {
             error = ret;
             n_errors++;
         }
         n_packets++;
     }
-    dp_packet_list_delete(&packets);
 
     if (n_errors) {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
-- 
2.1.4




More information about the dev mailing list