diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index f53cf65e87..c606fa9471 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -14702,22 +14702,34 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
 			    sizeof(struct mlx5_modification_cmd) *
 			    (MLX5_MAX_MODIFY_NUM + 1)];
 	} mhdr_dummy;
+	struct mlx5_flow_mtr_mng *mtrmng = priv->sh->mtrmng;
 
 	egress = (domain == MLX5_MTR_DOMAIN_EGRESS) ? 1 : 0;
 	transfer = (domain == MLX5_MTR_DOMAIN_TRANSFER) ? 1 : 0;
 	memset(&dh, 0, sizeof(struct mlx5_flow_handle));
 	memset(&dev_flow, 0, sizeof(struct mlx5_flow));
 	memset(&port_id_action, 0,
-		sizeof(struct mlx5_flow_dv_port_id_action_resource));
+	       sizeof(struct mlx5_flow_dv_port_id_action_resource));
 	dev_flow.handle = &dh;
 	dev_flow.dv.port_id_action = &port_id_action;
 	dev_flow.external = true;
 	for (i = 0; i < RTE_COLORS; i++) {
 		if (i < MLX5_MTR_RTE_COLORS)
 			act_cnt = &mtr_policy->act_cnt[i];
-		for (act = actions[i];
-			act && act->type != RTE_FLOW_ACTION_TYPE_END;
-			act++) {
+		act = actions[i];
+		/* No policy action, use default. */
+		if (!act || act->type == RTE_FLOW_ACTION_TYPE_END) {
+			if (!mtrmng->def_policy[domain])
+				return -rte_mtr_error_set(error,
+					ENOTSUP,
+					RTE_MTR_ERROR_TYPE_METER_POLICY,
+					NULL,
+					"Default policy not created.");
+			act_cnt->dr_jump_action[domain] =
+				mtrmng->def_policy[domain]->dr_jump_action[i];
+			continue;
+		}
+		for (; act->type != RTE_FLOW_ACTION_TYPE_END; act++) {
 			switch (act->type) {
 			case RTE_FLOW_ACTION_TYPE_MARK:
 			{
@@ -14933,6 +14945,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
 				action_flags |= MLX5_FLOW_ACTION_PORT_ID;
 				break;
 			}
+			/* G & Y can use the same table by default. */
 			case RTE_FLOW_ACTION_TYPE_JUMP:
 			{
 				uint32_t jump_group = 0;
@@ -14947,7 +14960,7 @@ __flow_dv_create_domain_policy_acts(struct rte_eth_dev *dev,
 					(1 << MLX5_SCALE_FLOW_GROUP_BIT),
 				};
 				struct mlx5_flow_meter_sub_policy *sub_policy =
-				mtr_policy->sub_policys[domain][0];
+					mtr_policy->sub_policys[domain][0];
 
 				if (i >= MLX5_MTR_RTE_COLORS)
 					return -rte_mtr_error_set(error,
@@ -15036,6 +15049,7 @@ flow_dv_create_mtr_policy_acts(struct rte_eth_dev *dev,
 			ret = __flow_dv_create_domain_policy_acts(dev,
 				mtr_policy, actions,
 				(enum mlx5_meter_domain)i, error);
+			/* Rollback is done in mlx5 layer. */
 			if (ret)
 				return ret;
 		}
@@ -15538,12 +15552,10 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
 
 	for (i = 0; i < RTE_COLORS; i++) {
 		acts[i].actions_n = 0;
-		if (i == RTE_COLOR_YELLOW)
-			continue;
 		if (i == RTE_COLOR_RED) {
 			/* Only support drop on red. */
 			acts[i].dv_actions[0] =
-			mtr_policy->dr_drop_action[domain];
+				mtr_policy->dr_drop_action[domain];
 			acts[i].actions_n = 1;
 			continue;
 		}
@@ -15555,13 +15567,12 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
 				"mark action for policy.");
 				return -1;
 			}
-			acts[i].dv_actions[acts[i].actions_n] =
-						tag->action;
+			acts[i].dv_actions[acts[i].actions_n] = tag->action;
 			acts[i].actions_n++;
 		}
 		if (mtr_policy->act_cnt[i].modify_hdr) {
 			acts[i].dv_actions[acts[i].actions_n] =
-			mtr_policy->act_cnt[i].modify_hdr->action;
+				mtr_policy->act_cnt[i].modify_hdr->action;
 			acts[i].actions_n++;
 		}
 		if (mtr_policy->act_cnt[i].fate_action) {
@@ -15576,7 +15587,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
 					return -1;
 				}
 				acts[i].dv_actions[acts[i].actions_n] =
-				port_action->action;
+					port_action->action;
 				acts[i].actions_n++;
 				break;
 			case MLX5_FLOW_FATE_DROP:
@@ -15588,15 +15599,15 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
 			case MLX5_FLOW_FATE_SHARED_RSS:
 			case MLX5_FLOW_FATE_QUEUE:
 				hrxq = mlx5_ipool_get
-				(priv->sh->ipool[MLX5_IPOOL_HRXQ],
-				sub_policy->rix_hrxq[i]);
+					(priv->sh->ipool[MLX5_IPOOL_HRXQ],
+					 sub_policy->rix_hrxq[i]);
 				if (!hrxq) {
 					DRV_LOG(ERR, "Failed to find "
 						"queue action for policy.");
 					return -1;
 				}
 				acts[i].dv_actions[acts[i].actions_n] =
-				hrxq->action;
+					hrxq->action;
 				acts[i].actions_n++;
 				break;
 			default:
@@ -15610,7 +15621,7 @@ __flow_dv_create_policy_acts_rules(struct rte_eth_dev *dev,
 	if (__flow_dv_create_domain_policy_rules(dev, sub_policy,
 				egress, transfer, false, acts)) {
 		DRV_LOG(ERR,
-		"Failed to create policy rules per domain.");
+			"Failed to create policy rules per domain.");
 		return -1;
 	}
 	return 0;
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 68351db1ce..025b469a1d 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -644,21 +644,20 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 	if (!priv->mtr_en)
 		return -rte_mtr_error_set(error, ENOTSUP,
 					  RTE_MTR_ERROR_TYPE_METER_POLICY,
-					  NULL, "meter policy unsupported.");
+					  NULL, "meter policy unsupported. ");
 	if (policy_id == MLX5_INVALID_POLICY_ID)
 		return -rte_mtr_error_set(error, ENOTSUP,
-			RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
-			"policy ID is invalid. ");
+					  RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+					  NULL, "policy ID is invalid. ");
 	if (policy_id == priv->sh->mtrmng->def_policy_id)
 		return -rte_mtr_error_set(error, EEXIST,
-			RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
-			"policy ID exists. ");
-	mtr_policy = mlx5_flow_meter_policy_find(dev, policy_id,
-				&policy_idx);
+					  RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+					  NULL, "default policy ID exists. ");
+	mtr_policy = mlx5_flow_meter_policy_find(dev, policy_id, &policy_idx);
 	if (mtr_policy)
 		return -rte_mtr_error_set(error, EEXIST,
-			RTE_MTR_ERROR_TYPE_METER_POLICY_ID, NULL,
-			"policy ID exists. ");
+					  RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
+					  NULL, "policy ID exists. ");
 	ret = mlx5_flow_validate_mtr_acts(dev, policy->actions, &attr,
 					  &is_rss, &domain_bitmap,
 					  &is_def_policy, error);
@@ -666,8 +665,8 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 		return ret;
 	if (!domain_bitmap)
 		return -rte_mtr_error_set(error, ENOTSUP,
-				RTE_MTR_ERROR_TYPE_METER_POLICY,
-				NULL, "fail to find policy domain.");
+					  RTE_MTR_ERROR_TYPE_METER_POLICY,
+					  NULL, "fail to find policy domain.");
 	if (is_def_policy) {
 		if (priv->sh->mtrmng->def_policy_id != MLX5_INVALID_POLICY_ID)
 			return -rte_mtr_error_set(error, EEXIST,
@@ -689,16 +688,22 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 	for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
 		if (!(domain_bitmap & (1 << i)))
 			continue;
+		/*
+		 * If RSS is found, it means that only the ingress domain can
+		 * be supported. It is invalid to support RSS for one color
+		 * and egress / transfer domain actions for another. Drop and
+		 * jump action should have no impact.
+		 */
 		if (is_rss) {
 			policy_size +=
-			sizeof(struct mlx5_flow_meter_sub_policy *) *
-			MLX5_MTR_RSS_MAX_SUB_POLICY;
+				sizeof(struct mlx5_flow_meter_sub_policy *) *
+				MLX5_MTR_RSS_MAX_SUB_POLICY;
 			break;
 		}
 		policy_size += sizeof(struct mlx5_flow_meter_sub_policy *);
 	}
 	mtr_policy = mlx5_malloc(MLX5_MEM_ZERO, policy_size,
-			 RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+				 RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
 	if (!mtr_policy)
 		return -rte_mtr_error_set(error, ENOMEM,
 				RTE_MTR_ERROR_TYPE_METER_POLICY, NULL,
@@ -715,7 +720,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 			mtr_policy->transfer = 1;
 		sub_policy = mlx5_ipool_zmalloc
 				(priv->sh->ipool[MLX5_IPOOL_MTR_POLICY],
-				&sub_policy_idx);
+				 &sub_policy_idx);
 		if (!sub_policy)
 			goto policy_add_err;
 		if (sub_policy_idx > MLX5_MAX_SUB_POLICY_TBL_NUM)
@@ -727,7 +732,7 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 			sub_policy->main_policy_id = 1;
 		}
 		mtr_policy->sub_policys[i] =
-		(struct mlx5_flow_meter_sub_policy **)
+			(struct mlx5_flow_meter_sub_policy **)
 			((uint8_t *)mtr_policy + policy_size);
 		mtr_policy->sub_policys[i][0] = sub_policy;
 		sub_policy_num = (mtr_policy->sub_policy_num >>
@@ -743,13 +748,17 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 			mtr_policy->is_rss = 1;
 			break;
 		}
-		policy_size += sizeof(struct mlx5_flow_meter_sub_policy  *);
+		policy_size += sizeof(struct mlx5_flow_meter_sub_policy *);
 	}
 	rte_spinlock_init(&mtr_policy->sl);
 	ret = mlx5_flow_create_mtr_acts(dev, mtr_policy,
 					policy->actions, error);
 	if (ret)
 		goto policy_add_err;
+	/*
+	 * If either Green or Yellow has queue / RSS action, all the policy
+	 * rules will be created later in the flow splitting stage.
+	 */
 	if (!is_rss && !mtr_policy->is_queue) {
 		/* Create policy rules in HW. */
 		ret = mlx5_flow_create_policy_rules(dev, mtr_policy);
