From f6081b2631ac124b73be5953a9b9ce4922bf505e Mon Sep 17 00:00:00 2001
From: lutong <lutong14@huawei.com>
Date: Mon, 28 Jul 2025 14:59:13 +0800
Subject: [PATCH 3/6] conf: add support for cachetune/L3 priority

---
 src/conf/domain_conf.c            | 29 +++++++++++++++++++++--------
 src/conf/schemas/domaincommon.rng |  1 +
 src/util/virresctrl.c             | 27 +++++++++++++++++++++++++--
 3 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9643b9ce01..5dbbe5cd3c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -17680,10 +17680,15 @@ virDomainCachetuneDefParseCache(xmlXPathContextPtr ctxt,
                        VIR_XML_PROP_REQUIRED, &type) < 0)
         return -1;
 
-    if (virParseScaledValue("./@size", "./@unit",
-                            ctxt, &size, 1024,
-                            ULLONG_MAX, true) < 0)
+    if (type == VIR_CACHE_TYPE_PRIORITY) {
+        if (virXMLPropULongLong(node, "size", 10, VIR_XML_PROP_REQUIRED, &size) < 0)
+            return -1;
+    } else {
+        if (virParseScaledValue("./@size", "./@unit",
+            ctxt, &size, 1024,
+            ULLONG_MAX, true) < 0)
         return -1;
+    }
 
     if (virResctrlAllocSetCacheSize(alloc, level, type, cache, size) < 0)
         return -1;
@@ -26749,11 +26754,19 @@ virDomainCachetuneDefFormatHelper(unsigned int level,
     virBuffer *buf = opaque;
     unsigned long long short_size = virFormatIntPretty(size, &unit);
 
-    virBufferAsprintf(buf,
-                      "<cache id='%u' level='%u' type='%s' "
-                      "size='%llu' unit='%s'/>\n",
-                      cache, level, virCacheTypeToString(type),
-                      short_size, unit);
+    if (type == VIR_CACHE_TYPE_PRIORITY) {
+        virBufferAsprintf(buf,
+                          "<cache id='%u' level='%u' type='%s' "
+                          "size='%llu'/>\n",
+                          cache, level, virCacheTypeToString(type),
+                          size);
+    } else {
+        virBufferAsprintf(buf,
+                        "<cache id='%u' level='%u' type='%s' "
+                        "size='%llu' unit='%s'/>\n",
+                        cache, level, virCacheTypeToString(type),
+                        short_size, unit);
+    }
 
     return 0;
 }
diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng
index f31603b2fd..7278b699e0 100644
--- a/src/conf/schemas/domaincommon.rng
+++ b/src/conf/schemas/domaincommon.rng
@@ -1147,6 +1147,7 @@
                       <value>both</value>
                       <value>code</value>
                       <value>data</value>
+                      <value>priority</value>
                     </choice>
                   </attribute>
                   <attribute name="size">
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
index 3d2be7560c..7bdbc85bc9 100644
--- a/src/util/virresctrl.c
+++ b/src/util/virresctrl.c
@@ -1184,6 +1184,15 @@ virResctrlAllocCheckCollision(virResctrlAlloc *alloc,
     if (!a_level)
         return false;
 
+    if (type == VIR_CACHE_TYPE_PRIORITY) {
+        a_type = a_level->types[VIR_CACHE_TYPE_PRIORITY];
+
+        if (a_type && a_type->nsizes > cache && a_type->sizes[cache])
+            return true;
+
+        return false;
+    }
+
     a_type = a_level->types[VIR_CACHE_TYPE_BOTH];
 
     /* If there is an allocation for type 'both', there can be no other
@@ -2330,14 +2339,28 @@ virResctrlAllocAssign(virResctrlInfo *resctrl,
                     if (!a_type->sizes[cache])
                         continue;
 
-                    if (!a_type->priorities[cache]) {
+                    if (a_type->npriorities == 0) {
                         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                             _("Cache level %1$d does not support tuning for scope type '%2$s'"),
                             level, virCacheTypeToString(type));
                         return -1;
                     }
 
-                    *a_type->priorities[cache] = *a_type->sizes[cache];
+                    if (a_type->npriorities <= cache || !a_type->priorities[cache]) {
+                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("Cache id %1$d does not exist for level %2$d"),
+                            cache, level);
+                        return -1;
+                    }
+
+                    if (*(a_type->sizes[cache]) > 3) {
+                        virReportError(VIR_ERR_XML_ERROR,
+                                       _("Cache level %1$d id %2$d priority value just support 0-3"),
+                                       level, cache);
+                        return -1;
+                    }
+
+                    *(a_type->priorities[cache]) = *(a_type->sizes[cache]);
                 }
                 continue;
             }
-- 
2.33.0