diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index 8992214ac8..4bdd0d727a 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -2,80 +2,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com>
 
-build_map_changes()
-{
-	local fname="$1"
-	local mapdb="$2"
-
-	cat "$fname" | awk '
-		# Initialize our variables
-		BEGIN {map="";sym="";ar="";sec=""; in_sec=0; in_map=0}
-
-		# Anything that starts with + or -, followed by an a
-		# and ends in the string .map is the name of our map file
-		# This may appear multiple times in a patch if multiple
-		# map files are altered, and all section/symbol names
-		# appearing between a triggering of this rule and the
-		# next trigger of this rule are associated with this file
-		/[-+] [ab]\/.*\.map/ {map=$2; in_map=1; next}
-
-		# The previous rule catches all .map files, anything else
-		# indicates we left the map chunk.
-		/[-+] [ab]\// {in_map=0}
-
-		# Triggering this rule, which starts a line and ends it
-		# with a { identifies a versioned section.  The section name is
-		# the rest of the line with the + and { symbols removed.
-		# Triggering this rule sets in_sec to 1, which actives the
-		# symbol rule below
-		/^.*{/ {
-			gsub("+", "");
-			if (in_map == 1) {
-				sec=$(NF-1); in_sec=1;
-			}
-		}
-
-		# This rule identifies the end of a section, and disables the
-		# symbol rule
-		/.*}/ {in_sec=0}
-
-		# This rule matches on a + followed by any characters except a :
-		# (which denotes a global vs local segment), and ends with a ;.
-		# The semicolon is removed and the symbol is printed with its
-		# association file name and version section, along with an
-		# indicator that the symbol is a new addition.  Note this rule
-		# only works if we have found a version section in the rule
-		# above (hence the in_sec check) And found a map file (the
-		# in_map check).  If we are not in a map chunk, do nothing.  If
-		# we are in a map chunk but not a section chunk, record it as
-		# unknown.
-		/^+[^}].*[^:*];/ {gsub(";","");sym=$2;
-			if (in_map == 1) {
-				if (in_sec == 1) {
-					print map " " sym " " sec " add"
-				} else {
-					print map " " sym " unknown add"
-				}
-			}
-		}
-
-		# This is the same rule as above, but the rule matches on a
-		# leading - rather than a +, denoting that the symbol is being
-		# removed.
-		/^-[^}].*[^:*];/ {gsub(";","");sym=$2;
-			if (in_map == 1) {
-				if (in_sec == 1) {
-					print map " " sym " " sec " del"
-				} else {
-					print map " " sym " unknown del"
-				}
-			}
-		}' > "$mapdb"
-
-		sort -u "$mapdb" > "$mapdb.2"
-		mv -f "$mapdb.2" "$mapdb"
-
-}
+selfdir=$(dirname $(readlink -f $0))
+. $selfdir/common-func.sh
 
 is_stable_section() {
 	[ "$1" != 'EXPERIMENTAL' ] && [ "$1" != 'INTERNAL' ]
diff --git a/devtools/check-trace-func.py b/devtools/check-trace-func.py
new file mode 100755
index 0000000000..d38d8616cd
--- /dev/null
+++ b/devtools/check-trace-func.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (C) 2022 Marvell.
+
+import sys
+
+patch = sys.argv[1]
+fn = sys.argv[2]
+
+with open(patch, 'r') as fr:
+	fstr = fr.read()
+
+def find_fn_def():
+	found = 0
+	tmp = 0
+	idx = 0
+	while found == 0:
+		idx = fstr.find("+"+fn+"(", idx)
+		if (idx != -1):
+			tmp = fstr.find(')', idx)
+			if (fstr[tmp + 1] == ';'):
+				idx = tmp
+				continue
+			else:
+				found = 1
+		else:
+			break
+	return idx
+
+def find_trace(index):
+	fp = fstr.find("{", index)
+	sp = fstr.find("}", fp)
+	fd = fstr[fp:sp]
+
+	i = fd.find("_trace_")
+	if (i != -1):
+		return 0
+	else:
+		return 1
+
+
+def __main():
+	ret=0
+	index = find_fn_def()
+	if (index != -1):
+		# If function definition is present,
+		# check if trace call is present
+		ret = find_trace(index)
+	return ret
+
+if __name__ == "__main__":
+	sys.exit(__main())
diff --git a/devtools/check-trace-func.sh b/devtools/check-trace-func.sh
new file mode 100755
index 0000000000..777b9a03e0
--- /dev/null
+++ b/devtools/check-trace-func.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (C) 2022 Marvell.
+
+selfdir=$(dirname $(readlink -f $0))
+. $selfdir/common-func.sh
+
+libdir="ethdev"
+check_for_trace_call()
+{
+	mapdb="$2"
+	ret=0
+
+	while read -r mname symname secname ar; do
+		libp=0
+		libname=$(echo $mname | awk 'BEGIN {FS="/"};{print $3}')
+
+		for i in $libdir; do
+			if [ $i = $libname ]; then
+				libp=1
+				break
+			fi
+		done
+
+		if [ $libp -eq 1 ] && [ "$ar" = "add" ]; then
+			if [ "$secname" = "EXPERIMENTAL" ]; then
+				# Check if new API is added with trace function call
+				if ! devtools/check-trace-func.py $1 $symname; then
+					ret=1
+					echo -n "ERROR: Function $symname "
+					echo "is added without trace call"
+				fi
+			fi
+		fi
+	done < "$mapdb"
+
+	return $ret
+}
+
+clean_and_exit_on_sig()
+{
+	rm -rf "$mapfile"
+}
+
+trap clean_and_exit_on_sig EXIT
+
+mapfile=$(mktemp -t dpdk.mapdb.XXXXXX)
+
+build_map_changes "$1" "$mapfile"
+check_for_trace_call "$1" "$mapfile"
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 1edc5810ad..35c47b3e85 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -10,6 +10,7 @@
 . $(dirname $(readlink -f $0))/load-devel-config
 
 VALIDATE_NEW_API=$(dirname $(readlink -f $0))/check-symbol-change.sh
+VALIDATE_TRACE_FUNC=$(dirname $(readlink -f $0))/check-trace-func.sh
 
 # Enable codespell by default. This can be overwritten from a config file.
 # Codespell can also be enabled by setting DPDK_CHECKPATCH_CODESPELL to a valid path
@@ -338,6 +339,14 @@ check () { # <patch> <commit> <title>
 		ret=1
 	fi
 
+	! $verbose || printf '\nChecking API additions with trace function call :\n'
+	report=$($VALIDATE_TRACE_FUNC "$tmpinput")
+	if [ $? -ne 0 ] ; then
+		$headline_printed || print_headline "$3"
+		printf '%s\n' "$report"
+		ret=1
+	fi
+
 	if [ "$tmpinput" != "$1" ]; then
 		rm -f "$tmpinput"
 		trap - INT
diff --git a/devtools/common-func.sh b/devtools/common-func.sh
new file mode 100644
index 0000000000..c88e949890
--- /dev/null
+++ b/devtools/common-func.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com>
+
+build_map_changes()
+{
+	local fname="$1"
+	local mapdb="$2"
+
+	cat "$fname" | awk '
+		# Initialize our variables
+		BEGIN {map="";sym="";ar="";sec=""; in_sec=0; in_map=0}
+
+		# Anything that starts with + or -, followed by an a
+		# and ends in the string .map is the name of our map file
+		# This may appear multiple times in a patch if multiple
+		# map files are altered, and all section/symbol names
+		# appearing between a triggering of this rule and the
+		# next trigger of this rule are associated with this file
+		/[-+] [ab]\/.*\.map/ {map=$2; in_map=1; next}
+
+		# The previous rule catches all .map files, anything else
+		# indicates we left the map chunk.
+		/[-+] [ab]\// {in_map=0}
+
+		# Triggering this rule, which starts a line and ends it
+		# with a { identifies a versioned section.  The section name is
+		# the rest of the line with the + and { symbols removed.
+		# Triggering this rule sets in_sec to 1, which actives the
+		# symbol rule below
+		/^.*{/ {
+			gsub("+", "");
+			if (in_map == 1) {
+				sec=$(NF-1); in_sec=1;
+			}
+		}
+
+		# This rule identifies the end of a section, and disables the
+		# symbol rule
+		/.*}/ {in_sec=0}
+
+		# This rule matches on a + followed by any characters except a :
+		# (which denotes a global vs local segment), and ends with a ;.
+		# The semicolon is removed and the symbol is printed with its
+		# association file name and version section, along with an
+		# indicator that the symbol is a new addition.  Note this rule
+		# only works if we have found a version section in the rule
+		# above (hence the in_sec check) And found a map file (the
+		# in_map check).  If we are not in a map chunk, do nothing.  If
+		# we are in a map chunk but not a section chunk, record it as
+		# unknown.
+		/^+[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_map == 1) {
+				if (in_sec == 1) {
+					print map " " sym " " sec " add"
+				} else {
+					print map " " sym " unknown add"
+				}
+			}
+		}
+
+		# This is the same rule as above, but the rule matches on a
+		# leading - rather than a +, denoting that the symbol is being
+		# removed.
+		/^-[^}].*[^:*];/ {gsub(";","");sym=$2;
+			if (in_map == 1) {
+				if (in_sec == 1) {
+					print map " " sym " " sec " del"
+				} else {
+					print map " " sym " unknown del"
+				}
+			}
+		}' > "$mapdb"
+
+		sort -u "$mapdb" > "$mapdb.2"
+		mv -f "$mapdb.2" "$mapdb"
+}
