diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index b0ecdb6..fcc4635 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -2567,24 +2567,42 @@ start_vhost_loop(void *dummy OVS_UNUSED)
 }
 
 static int
-dpdk_vhost_class_init(void)
+netdev_dpdk_class_init(void)
 {
-    rte_vhost_driver_callback_register(&virtio_net_device_ops);
-    rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4
-                            | 1ULL << VIRTIO_NET_F_HOST_TSO6
-                            | 1ULL << VIRTIO_NET_F_CSUM);
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
+
+    /* This function can be called for different classes.  The initialization
+     * needs to be done only once */
+    if (ovsthread_once_start(&once)) {
+        ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL);
+        unixctl_command_register("netdev-dpdk/set-admin-state",
+                                 "[netdev] up|down", 1, 2,
+                                 netdev_dpdk_set_admin_state, NULL);
+
+        ovsthread_once_done(&once);
+    }
 
-    ovs_thread_create("vhost_thread", start_vhost_loop, NULL);
     return 0;
 }
 
-static void
-dpdk_common_init(void)
+static int
+netdev_dpdk_vhost_class_init(void)
 {
-    unixctl_command_register("netdev-dpdk/set-admin-state",
-                             "[netdev] up|down", 1, 2,
-                             netdev_dpdk_set_admin_state, NULL);
+    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
 
+    /* This function can be called for different classes.  The initialization
+     * needs to be done only once */
+    if (ovsthread_once_start(&once)) {
+        rte_vhost_driver_callback_register(&virtio_net_device_ops);
+        rte_vhost_feature_disable(1ULL << VIRTIO_NET_F_HOST_TSO4
+                                  | 1ULL << VIRTIO_NET_F_HOST_TSO6
+                                  | 1ULL << VIRTIO_NET_F_CSUM);
+        ovs_thread_create("vhost_thread", start_vhost_loop, NULL);
+
+        ovsthread_once_done(&once);
+    }
+
+    return 0;
 }
 
 /* Client Rings */
@@ -3033,7 +3051,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)
     return 0;
 }
 
-#define NETDEV_DPDK_CLASS(NAME, CONSTRUCT, DESTRUCT,          \
+#define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, DESTRUCT,    \
                           SET_CONFIG, SET_TX_MULTIQ, SEND,    \
                           GET_CARRIER, GET_STATS,             \
                           GET_FEATURES, GET_STATUS,           \
@@ -3041,7 +3059,7 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)
 {                                                             \
     NAME,                                                     \
     true,                       /* is_pmd */                  \
-    NULL,                       /* init */                    \
+    INIT,                       /* init */                    \
     NULL,                       /* netdev_dpdk_run */         \
     NULL,                       /* netdev_dpdk_wait */        \
                                                               \
@@ -3459,10 +3477,6 @@ dpdk_init__(const struct smap *ovs_other_config)
     /* We are called from the main thread here */
     RTE_PER_LCORE(_lcore_id) = NON_PMD_CORE_ID;
 
-    ovs_thread_create("dpdk_watchdog", dpdk_watchdog, NULL);
-
-    dpdk_vhost_class_init();
-
 #ifdef DPDK_PDUMP
     VLOG_INFO("DPDK pdump packet capture enabled");
     err = rte_pdump_init(ovs_rundir());
@@ -3497,6 +3511,7 @@ dpdk_init(const struct smap *ovs_other_config)
 static const struct netdev_class dpdk_class =
     NETDEV_DPDK_CLASS(
         "dpdk",
+        netdev_dpdk_class_init,
         netdev_dpdk_construct,
         netdev_dpdk_destruct,
         netdev_dpdk_set_config,
@@ -3512,6 +3527,7 @@ static const struct netdev_class dpdk_class =
 static const struct netdev_class dpdk_ring_class =
     NETDEV_DPDK_CLASS(
         "dpdkr",
+        netdev_dpdk_class_init,
         netdev_dpdk_ring_construct,
         netdev_dpdk_destruct,
         netdev_dpdk_ring_set_config,
@@ -3527,6 +3543,7 @@ static const struct netdev_class dpdk_ring_class =
 static const struct netdev_class dpdk_vhost_class =
     NETDEV_DPDK_CLASS(
         "dpdkvhostuser",
+        netdev_dpdk_vhost_class_init,
         netdev_dpdk_vhost_construct,
         netdev_dpdk_vhost_destruct,
         NULL,
@@ -3541,6 +3558,7 @@ static const struct netdev_class dpdk_vhost_class =
 static const struct netdev_class dpdk_vhost_client_class =
     NETDEV_DPDK_CLASS(
         "dpdkvhostuserclient",
+        netdev_dpdk_vhost_class_init,
         netdev_dpdk_vhost_client_construct,
         netdev_dpdk_vhost_destruct,
         netdev_dpdk_vhost_client_set_config,
@@ -3556,7 +3574,6 @@ static const struct netdev_class dpdk_vhost_client_class =
 void
 netdev_dpdk_register(void)
 {
-    dpdk_common_init();
     netdev_register_provider(&dpdk_class);
     netdev_register_provider(&dpdk_ring_class);
     netdev_register_provider(&dpdk_vhost_class);
