]> git.proxmox.com Git - mirror_ovs.git/commitdiff
netdev: Add n_txq to 'struct netdev'.
authorAlex Wang <alexw@nicira.com>
Wed, 3 Sep 2014 21:37:35 +0000 (14:37 -0700)
committerAlex Wang <alexw@nicira.com>
Fri, 12 Sep 2014 18:30:58 +0000 (11:30 -0700)
This commit adds new variable n_txq to 'struct netdev' for recording
the number of tx queues.  Correspondingly, the send_*() functions are
extended to accept queue id as input argument.

All 'netdev-*' implementation will ignore the queue id since having
multiple tx queues is not supported.  Upcomping patches will start
using it and create multiple tx queues for dpdk netdev.

Signed-off-by: Alex Wang <alexw@nicira.com>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
lib/dpif-netdev.c
lib/dpif-netdev.h
lib/netdev-bsd.c
lib/netdev-dpdk.c
lib/netdev-dummy.c
lib/netdev-linux.c
lib/netdev-provider.h
lib/netdev.c
lib/netdev.h

index a4dabb6ad7eaa09e9e0e654b659ce666cd57c094..5486dd637bd40b20d3ae04714eceb094f9ab8d08 100644 (file)
@@ -2435,7 +2435,7 @@ dp_execute_cb(void *aux_, struct dpif_packet **packets, int cnt,
     case OVS_ACTION_ATTR_OUTPUT:
         p = dp_netdev_lookup_port(dp, u32_to_odp(nl_attr_get_u32(a)));
         if (OVS_LIKELY(p)) {
-            netdev_send(p->netdev, packets, cnt, may_steal);
+            netdev_send(p->netdev, NETDEV_QID_NONE, packets, cnt, may_steal);
         } else if (may_steal) {
             for (i = 0; i < cnt; i++) {
                 dpif_packet_delete(packets[i]);
index 410fcfa1554f6490d25f549562c2b06cd7f12c25..fb9d0e276abede6fc51c3096290b7b046fde8016 100644 (file)
@@ -40,6 +40,8 @@ static inline void dp_packet_pad(struct ofpbuf *b)
     }
 }
 
+#define NETDEV_QID_NONE INT_MAX
+
 #define NR_QUEUE   1
 #define NR_PMD_THREADS 1
 
index dd1893c8606f371fadbe932ce2215635fab4bbd1..32c04a38c5ba2d291ceda1dda8d1ce6043155492 100644 (file)
@@ -687,8 +687,8 @@ netdev_bsd_rxq_drain(struct netdev_rxq *rxq_)
  * system or a tap device.
  */
 static int
-netdev_bsd_send(struct netdev *netdev_, struct dpif_packet **pkts, int cnt,
-                bool may_steal)
+netdev_bsd_send(struct netdev *netdev_, int qid OVS_UNUSED,
+                struct dpif_packet **pkts, int cnt, bool may_steal)
 {
     struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
     const char *name = netdev_get_name(netdev_);
@@ -750,7 +750,7 @@ netdev_bsd_send(struct netdev *netdev_, struct dpif_packet **pkts, int cnt,
  * with netdev_send().
  */
 static void
-netdev_bsd_send_wait(struct netdev *netdev_)
+netdev_bsd_send_wait(struct netdev *netdev_, int qid OVS_UNUSED)
 {
     struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
 
index 70ee8db838db4c691c5842955e0606a6028dd1b9..4f9c5c2a2122aceab0054b7c1d533d2509463dc1 100644 (file)
@@ -495,6 +495,7 @@ netdev_dpdk_init(struct netdev *netdev_, unsigned int port_no) OVS_REQUIRES(dpdk
     if (err) {
         goto unlock;
     }
+    netdev_->n_txq = NR_QUEUE;
     netdev_->n_rxq = NR_QUEUE;
 
     list_push_back(&dpdk_list, &netdev->list_node);
@@ -792,8 +793,8 @@ dpdk_do_tx_copy(struct netdev *netdev, struct dpif_packet ** pkts, int cnt)
 }
 
 static int
-netdev_dpdk_send(struct netdev *netdev, struct dpif_packet **pkts, int cnt,
-                 bool may_steal)
+netdev_dpdk_send(struct netdev *netdev, int qid, struct dpif_packet **pkts,
+                 int cnt, bool may_steal)
 {
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
     int ret;
@@ -808,7 +809,6 @@ netdev_dpdk_send(struct netdev *netdev, struct dpif_packet **pkts, int cnt,
             }
         }
     } else {
-        int qid;
         int next_tx_idx = 0;
         int dropped = 0;
 
index ecb0821e324233389194ef2e9cd890c440317c63..1334a674fbf3563700cb13175e6e3a3f51a85901 100644 (file)
@@ -847,8 +847,8 @@ netdev_dummy_rxq_drain(struct netdev_rxq *rxq_)
 }
 
 static int
-netdev_dummy_send(struct netdev *netdev, struct dpif_packet **pkts, int cnt,
-                  bool may_steal)
+netdev_dummy_send(struct netdev *netdev, int qid OVS_UNUSED,
+                  struct dpif_packet **pkts, int cnt, bool may_steal)
 {
     struct netdev_dummy *dev = netdev_dummy_cast(netdev);
     int error = 0;
index 298ccd6a974f97fdba32fec59070add4366862a1..e31112253ba7a821a77c8b42014a60db25cbd9dc 100644 (file)
@@ -1057,8 +1057,8 @@ netdev_linux_rxq_drain(struct netdev_rxq *rxq_)
  * The kernel maintains a packet transmission queue, so the caller is not
  * expected to do additional queuing of packets. */
 static int
-netdev_linux_send(struct netdev *netdev_, struct dpif_packet **pkts, int cnt,
-                  bool may_steal)
+netdev_linux_send(struct netdev *netdev_, int qid OVS_UNUSED,
+                  struct dpif_packet **pkts, int cnt, bool may_steal)
 {
     int i;
     int error = 0;
@@ -1161,7 +1161,7 @@ netdev_linux_send(struct netdev *netdev_, struct dpif_packet **pkts, int cnt,
  * expected to do additional queuing of packets.  Thus, this function is
  * unlikely to ever be used.  It is included for completeness. */
 static void
-netdev_linux_send_wait(struct netdev *netdev)
+netdev_linux_send_wait(struct netdev *netdev, int qid OVS_UNUSED)
 {
     if (is_tap_netdev(netdev)) {
         /* TAP device always accepts packets.*/
index e8f2ebe422d761638f0db7914c54752517e4be0e..c08ef351943f721901ad5d3da4565dab984bb3fa 100644 (file)
@@ -52,6 +52,7 @@ struct netdev {
     uint64_t change_seq;
 
     /* The following are protected by 'netdev_mutex' (internal to netdev.c). */
+    int n_txq;
     int n_rxq;
     int ref_cnt;                        /* Times this devices was opened. */
     struct shash_node *node;            /* Pointer to element in global map. */
@@ -258,8 +259,8 @@ struct netdev_class {
     int (*get_numa_id)(const struct netdev *netdev);
 
     /* Sends buffers on 'netdev'.
-     * Returns 0 if successful (for every buffer), otherwise a positive errno value.
-     * Returns EAGAIN without blocking if one or more packets cannot be
+     * Returns 0 if successful (for every buffer), otherwise a positive errno
+     * value.  Returns EAGAIN without blocking if one or more packets cannot be
      * queued immediately. Returns EMSGSIZE if a partial packet was transmitted
      * or if a packet is too big or too small to transmit on the device.
      *
@@ -268,9 +269,11 @@ struct netdev_class {
      *
      * To retain ownership of 'buffers' caller can set may_steal to false.
      *
-     * The network device is expected to maintain a packet transmission queue,
-     * so that the caller does not ordinarily have to do additional queuing of
-     * packets.
+     * The network device is expected to maintain one or more packet
+     * transmission queues, so that the caller does not ordinarily have to
+     * do additional queuing of packets.  'qid' specifies the queue to use
+     * and can be ignored if the implementation does not support multiple
+     * queues.
      *
      * May return EOPNOTSUPP if a network device does not implement packet
      * transmission through this interface.  This function may be set to null
@@ -278,20 +281,22 @@ struct netdev_class {
      * network device from being usefully used by the netdev-based "userspace
      * datapath".  It will also prevent the OVS implementation of bonding from
      * working properly over 'netdev'.) */
-    int (*send)(struct netdev *netdev, struct dpif_packet **buffers, int cnt,
-                bool may_steal);
+    int (*send)(struct netdev *netdev, int qid, struct dpif_packet **buffers,
+                int cnt, bool may_steal);
 
     /* Registers with the poll loop to wake up from the next call to
      * poll_block() when the packet transmission queue for 'netdev' has
      * sufficient room to transmit a packet with netdev_send().
      *
-     * The network device is expected to maintain a packet transmission queue,
-     * so that the caller does not ordinarily have to do additional queuing of
-     * packets.  Thus, this function is unlikely to ever be useful.
+     * The network device is expected to maintain one or more packet
+     * transmission queues, so that the caller does not ordinarily have to
+     * do additional queuing of packets.  'qid' specifies the queue to use
+     * and can be ignored if the implementation does not support multiple
+     * queues.
      *
      * May be null if not needed, such as for a network device that does not
      * implement packet transmission through the 'send' member function. */
-    void (*send_wait)(struct netdev *netdev);
+    void (*send_wait)(struct netdev *netdev, int qid);
 
     /* Sets 'netdev''s Ethernet address to 'mac' */
     int (*set_etheraddr)(struct netdev *netdev, const uint8_t mac[6]);
index 444ae853e005ac44a4eb70a0bb0daf7927ece3ae..0d065e74511c366bb9c15925f8bb3e63ee1a1970 100644 (file)
@@ -91,6 +91,12 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
 static void restore_all_flags(void *aux OVS_UNUSED);
 void update_device_args(struct netdev *, const struct shash *args);
 
+int
+netdev_n_txq(const struct netdev *netdev)
+{
+    return netdev->n_txq;
+}
+
 int
 netdev_n_rxq(const struct netdev *netdev)
 {
@@ -355,12 +361,10 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
                 netdev->change_seq = 1;
                 netdev->node = shash_add(&netdev_shash, name, netdev);
 
-                /* By default enable one rx queue per netdev. */
-                if (netdev->netdev_class->rxq_alloc) {
-                    netdev->n_rxq = 1;
-                } else {
-                    netdev->n_rxq = 0;
-                }
+                /* 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;
+
                 list_init(&netdev->saved_flags_list);
 
                 error = rc->class->construct(netdev);
@@ -670,19 +674,22 @@ netdev_rxq_drain(struct netdev_rxq *rx)
  *
  * To retain ownership of 'buffer' caller can set may_steal to false.
  *
- * The kernel maintains a packet transmission queue, so the caller is not
- * expected to do additional queuing of packets.
+ * The network device is expected to maintain one or more packet
+ * transmission queues, so that the caller does not ordinarily have to
+ * do additional queuing of packets.  'qid' specifies the queue to use
+ * and can be ignored if the implementation does not support multiple
+ * queues.
  *
  * Some network devices may not implement support for this function.  In such
  * cases this function will always return EOPNOTSUPP. */
 int
-netdev_send(struct netdev *netdev, struct dpif_packet **buffers, int cnt,
-            bool may_steal)
+netdev_send(struct netdev *netdev, int qid, struct dpif_packet **buffers,
+            int cnt, bool may_steal)
 {
     int error;
 
     error = (netdev->netdev_class->send
-             ? netdev->netdev_class->send(netdev, buffers, cnt, may_steal)
+             ? netdev->netdev_class->send(netdev, qid, buffers, cnt, may_steal)
              : EOPNOTSUPP);
     if (!error) {
         COVERAGE_INC(netdev_sent);
@@ -694,14 +701,16 @@ netdev_send(struct netdev *netdev, struct dpif_packet **buffers, int cnt,
  * when the packet transmission queue has sufficient room to transmit a packet
  * with netdev_send().
  *
- * The kernel maintains a packet transmission queue, so the client is not
- * expected to do additional queuing of packets.  Thus, this function is
- * unlikely to ever be used.  It is included for completeness. */
+ * The network device is expected to maintain one or more packet
+ * transmission queues, so that the caller does not ordinarily have to
+ * do additional queuing of packets.  'qid' specifies the queue to use
+ * and can be ignored if the implementation does not support multiple
+ * queues. */
 void
-netdev_send_wait(struct netdev *netdev)
+netdev_send_wait(struct netdev *netdev, int qid)
 {
     if (netdev->netdev_class->send_wait) {
-        netdev->netdev_class->send_wait(netdev);
+        netdev->netdev_class->send_wait(netdev, qid);
     }
 }
 
index f429bc6a7ca0545bf57a169f5eb2e8dbacf284fa..c6249c452c666ce564876a8f9d974791ea9f5354 100644 (file)
@@ -135,6 +135,7 @@ void netdev_wait(void);
 void netdev_enumerate_types(struct sset *types);
 bool netdev_is_reserved_name(const char *name);
 
+int netdev_n_txq(const struct netdev *netdev);
 int netdev_n_rxq(const struct netdev *netdev);
 bool netdev_is_pmd(const struct netdev *netdev);
 
@@ -174,9 +175,9 @@ void netdev_rxq_wait(struct netdev_rxq *);
 int netdev_rxq_drain(struct netdev_rxq *);
 
 /* Packet transmission. */
-int netdev_send(struct netdev *, struct dpif_packet **, int cnt,
+int netdev_send(struct netdev *, int qid, struct dpif_packet **, int cnt,
                 bool may_steal);
-void netdev_send_wait(struct netdev *);
+void netdev_send_wait(struct netdev *, int qid);
 
 /* Hardware address. */
 int netdev_set_etheraddr(struct netdev *, const uint8_t mac[6]);