diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index 5a3400e..6ef3003 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -23,6 +23,10 @@ struct rte_logs rte_logs = {
 	.file = NULL,
 };
 
+/** Global list of valid EAL log level options */
+struct rte_eal_opt_loglevel_list opt_loglevel_list =
+	TAILQ_HEAD_INITIALIZER(opt_loglevel_list);
+
 /* Stream to use for logging if rte_logs.file is NULL */
 static FILE *default_log_stream;
 
@@ -184,6 +188,38 @@ rte_log_register(const char *name)
 	return ret;
 }
 
+/* Register an extended log type and try to pick its level from EAL options */
+int
+rte_log_register_type_and_pick_level(const char *name, uint32_t level_def)
+{
+	struct rte_eal_opt_loglevel *opt_ll;
+	uint32_t level = level_def;
+	int type;
+
+	type = rte_log_register(name);
+	if (type < 0)
+		return type;
+
+	TAILQ_FOREACH(opt_ll, &opt_loglevel_list, next) {
+		regex_t r;
+
+		if (opt_ll->level > RTE_LOG_DEBUG)
+			continue;
+
+		if (regcomp(&r, opt_ll->re_type, 0) != 0)
+			continue;
+
+		if (regexec(&r, name, 0, NULL, 0) == 0)
+			level = opt_ll->level;
+
+		regfree(&r);
+	}
+
+	rte_logs.dynamic_types[type].loglevel = level;
+
+	return type;
+}
+
 struct logtype {
 	uint32_t log_id;
 	const char *logtype;
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 996a034..b7b44d5 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -971,6 +971,29 @@ eal_parse_log_level(const char *arg)
 		printf("cannot set log level %s,%lu\n",
 			type, tmp);
 		goto fail;
+	} else {
+		struct rte_eal_opt_loglevel *opt_ll;
+
+		/*
+		 * Save the type (regexp string) and the loglevel
+		 * in the global storage so that it could be used
+		 * to configure dynamic logtypes which are absent
+		 * at the moment of EAL option processing but may
+		 * be registered during runtime.
+		 */
+		opt_ll = malloc(sizeof(*opt_ll));
+		if (opt_ll == NULL)
+			goto fail;
+
+		opt_ll->re_type = strdup(type);
+		if (opt_ll->re_type == NULL) {
+			free(opt_ll);
+			goto fail;
+		}
+
+		opt_ll->level = tmp;
+
+		TAILQ_INSERT_HEAD(&opt_loglevel_list, opt_ll, next);
 	}
 
 	free(str);
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 9029c78..5f4799e 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -20,6 +20,7 @@ extern "C" {
 #include <stdint.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <sys/queue.h>
 
 #include <rte_common.h>
 #include <rte_config.h>
@@ -85,6 +86,32 @@ extern struct rte_logs rte_logs;
 #define RTE_LOG_DEBUG    8U  /**< Debug-level messages.             */
 
 /**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Entry definition for the storage to keep EAL log level options
+ * which are found to have log type regular expressions specified.
+ */
+struct rte_eal_opt_loglevel {
+	/** Next list entry */
+	TAILQ_ENTRY(rte_eal_opt_loglevel) next;
+	/** Regular expression string obtained from the option */
+	char *re_type;
+	/** Log level value obtained from the option */
+	uint32_t level;
+};
+
+TAILQ_HEAD(rte_eal_opt_loglevel_list, rte_eal_opt_loglevel);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Global list of EAL log level options featuring log type expressions
+ */
+extern struct rte_eal_opt_loglevel_list opt_loglevel_list;
+
+/**
  * Change the stream that will be used by the logging system.
  *
  * This can be done at any time. The f argument represents the stream
@@ -195,6 +222,27 @@ int rte_log_cur_msg_logtype(void);
 int rte_log_register(const char *name);
 
 /**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Register a dynamic log type and try to pick its level from EAL options
+ *
+ * rte_log_register() is called inside. If successful, the function tries
+ * to search for matching regexp in the list of EAL log level options and
+ * pick the level from the last matching entry. If nothing can be applied
+ * from the list, the level will be set to the user-defined default value.
+ *
+ * @param name
+ *    Name for the log type to be registered
+ * @param level_def
+ *    Fallback level to be set if the global list has no matching options
+ * @return
+ *    - >=0: the newly registered log type
+ *    - <0: rte_log_register() error value
+ */
+int rte_log_register_type_and_pick_level(const char *name, uint32_t level_def);
+
+/**
  * Dump log information.
  *
  * Dump the global level and the registered log types.
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 7088b72..7e931a9 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -217,6 +217,7 @@ EXPERIMENTAL {
 	rte_eal_devargs_remove;
 	rte_eal_hotplug_add;
 	rte_eal_hotplug_remove;
+	rte_log_register_type_and_pick_level;
 	rte_service_attr_get;
 	rte_service_attr_reset_all;
 	rte_service_component_register;
