From 125bf78ea47530ac78f3558855b9e612ef76ce46 Mon Sep 17 00:00:00 2001
From: Roman Dementiev <roman.dementiev@intel.com>
Date: Sat, 16 Mar 2024 14:02:48 +0100
Subject: [PATCH 01/22] disable less useful metrics

---
 src/pcm.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/pcm.cpp b/src/pcm.cpp
index f257252f..74ffedd5 100644
--- a/src/pcm.cpp
+++ b/src/pcm.cpp
@@ -359,7 +359,7 @@ void print_output(PCM * m,
         drawStackedBar(" Core    C-state distribution", CoreCStateStackedBar, 80);
         drawStackedBar(" Package C-state distribution", PackageCStateStackedBar, 80);
 
-        if (m->getNumCores() == m->getNumOnlineCores())
+        if (m->getNumCores() == m->getNumOnlineCores() && false)
         {
             cout << "\n PHYSICAL CORE IPC                 : " << getCoreIPC(sstate1, sstate2) << " => corresponds to " << 100. * (getCoreIPC(sstate1, sstate2) / double(m->getMaxIPC())) << " % utilization for cores in active state";
             cout << "\n Instructions per nominal CPU cycle: " << getTotalExecUsage(sstate1, sstate2) << " => corresponds to " << 100. * (getTotalExecUsage(sstate1, sstate2) / double(m->getMaxIPC())) << " % core utilization over time interval\n";
@@ -393,7 +393,9 @@ void print_output(PCM * m,
             cout << "\n";
         }
 
+#if 0
         cout << " SMI count: " << getSMICount(sstate1, sstate2) << "\n";
+#endif
     }
 
     if (show_socket_output)

From e8a7a772a9e13e0542ea2b784b66940f858c4747 Mon Sep 17 00:00:00 2001
From: Roman Dementiev <roman.dementiev@intel.com>
Date: Sat, 16 Mar 2024 14:08:42 +0100
Subject: [PATCH 02/22] pcm: make metric version 2 default

---
 src/pcm.cpp | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/pcm.cpp b/src/pcm.cpp
index 74ffedd5..ca2f0538 100644
--- a/src/pcm.cpp
+++ b/src/pcm.cpp
@@ -93,8 +93,7 @@ void print_help(const string & prog_name)
         << "                                        to a file, in case filename is provided\n"
         << "                                        the format used is documented here: https://www.intel.com/content/www/us/en/developer/articles/technical/intel-pcm-column-names-decoder-ring.html\n";
     cout << "  -i[=number] | /i[=number]          => allow to determine number of iterations\n";
-    cout << "  -m=integer | /m=integer            => metrics version (default = 1). If version is 2\n"
-         << "                                        then a few alternative metrics are shown (UTIL=C0 residency for cores, CFREQ=core frequency in GHz).\n";
+    cout << "  -m=integer | /m=integer            => metrics version (default = 2)\n";
     print_enforce_flush_option_help();
     print_help_force_rtm_abort_mode(37);
     cout << " Examples:\n";
@@ -1292,7 +1291,7 @@ int mainThrows(int argc, char * argv[])
     bool reset_pmu = false;
     bool disable_JKT_workaround = false; // as per http://software.intel.com/en-us/articles/performance-impact-when-sampling-certain-llc-events-on-snb-ep-with-vtune
     bool enforceFlush = false;
-    int metricVersion = 1;
+    int metricVersion = 2;
 
     parsePID(argc, argv, pid);
 
@@ -1391,7 +1390,7 @@ int mainThrows(int argc, char * argv[])
             }
             if (metricVersion == 0)
             {
-                metricVersion = 1;
+                metricVersion = 2;
             }
             continue;
         }

From 41d2d1ce76558c13e0c3f34fe5e243af76129072 Mon Sep 17 00:00:00 2001
From: Roman Dementiev <roman.dementiev@intel.com>
Date: Sat, 16 Mar 2024 14:57:22 +0100
Subject: [PATCH 03/22] Update CONTRIBUTING.md

---
 CONTRIBUTING.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 502865e8..8cf6a0c6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,7 +8,7 @@ Everyone is welcome to contribute. Patches may be submitted using GitHub pull re
 License
 --------------------------------------------------------------------------------
 
-(Intel&reg; PCM) is licensed using a [BSD 3-clause license](https://github.com/intel/pcm/blob/master/LICENSE). All code submitted to the project is required to carry that license.
+Intel&reg; PCM is licensed using a [BSD 3-clause license](https://github.com/intel/pcm/blob/master/LICENSE). All code submitted to the project is required to carry that license.
 
 --------------------------------------------------------------------------------
 Coding Style

From ae83519854b53ac76470c7caca173aafb30dbbb2 Mon Sep 17 00:00:00 2001
From: Roman Dementiev <roman.dementiev@intel.com>
Date: Sat, 16 Mar 2024 14:58:09 +0100
Subject: [PATCH 04/22] Update CONTRIBUTING.md

---
 CONTRIBUTING.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8cf6a0c6..a1ba64ad 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -14,4 +14,4 @@ Intel&reg; PCM is licensed using a [BSD 3-clause license](https://github.com/int
 Coding Style
 --------------------------------------------------------------------------------
 
-While we don't enforce stringent coding style requirements, we do encourage adherence to standard coding style practices, such as those outlined in the Google C++ Style Guide (https://google.github.io/styleguide/cppguide.html). When submitting patches, we request that you maintain the style consistency with the surrounding code. We discourage the use of tabs; please use 4 spaces for indentation instead.
+While we don't enforce stringent coding style requirements, we do encourage adherence to standard coding style practices, such as those outlined in the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html). When submitting patches, we request that you maintain the style consistency with the surrounding code. We discourage the use of tabs; please use 4 spaces for indentation instead.

From e1b297078b859f48ce670ff097f4929ad47b03ea Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Tue, 2 Apr 2024 16:31:08 +0200
Subject: [PATCH 05/22] fix crash on BDX when trying to program IRP or IIO PMU

Change-Id: Icc9b6fdc4d32618eecc0e5e3e3e8a62184983c58
---
 src/cpucounters.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index feab19f7..d1646b2d 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -2430,9 +2430,9 @@ void PCM::initUncorePMUsDirect()
         IRP_UNIT_CTL = SPR_IRP_UNIT_CTL;
         break;
     }
+    irpPMUs.resize(num_sockets);
     if (IRP_UNIT_CTL)
     {
-        irpPMUs.resize(num_sockets);
         for (uint32 s = 0; s < (uint32)num_sockets; ++s)
         {
             auto& handle = MSR[socketRefCore[s]];
@@ -9270,6 +9270,7 @@ uint32 PCM::getMaxNumOfIIOStacks() const
 {
     if (iioPMUs.size() > 0)
     {
+        assert(irpPMUs.size());
         assert(iioPMUs[0].size() == irpPMUs[0].size());
         return (uint32)iioPMUs[0].size();
     }

From 7599cf3798405a37c8ffc29b26ae8b763c4ab2d7 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Tue, 2 Apr 2024 17:47:22 +0200
Subject: [PATCH 06/22] add MTL support

address https://github.com/intel/pcm/issues/713

Change-Id: I12c01aafe88c545c3202b0db4d87c19643e24283
---
 src/cpucounters.cpp | 12 ++++++++++--
 src/cpucounters.h   | 19 +++++++++++++++++--
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index d1646b2d..0f3235fc 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -697,6 +697,7 @@ void PCM::initCStateSupportTables()
         case DENVERTON:
         case ADL:
         case RPL:
+        case MTL:
         case SNOWRIDGE:
             PCM_CSTATE_ARRAY(pkgCStateMsr, PCM_PARAM_PROTECT({0, 0, 0x3F8, 0, 0x3F9, 0, 0x3FA, 0, 0, 0, 0 }) );
         case NEHALEM_EP:
@@ -769,6 +770,7 @@ void PCM::initCStateSupportTables()
         PCM_SKL_PATH_CASES
         case ADL:
         case RPL:
+        case MTL:
         case SNOWRIDGE:
         case ICX:
         case SPR:
@@ -1595,6 +1597,7 @@ bool PCM::detectNominalFrequency()
                || cpu_model == KNL
                || cpu_model == ADL
                || cpu_model == RPL
+               || cpu_model == MTL
                || cpu_model == SKX
                || cpu_model == ICX
                || cpu_model == SPR
@@ -1853,7 +1856,8 @@ void PCM::initUncoreObjects()
            {
            case TGL:
            case ADL: // TGLClientBW works fine for ADL
-           case RPL: // TGLClientBW works fine for ADL
+           case RPL: // TGLClientBW works fine for RPL
+           case MTL: // TGLClientBW works fine for MTL
                clientBW = std::make_shared<TGLClientBW>();
                break;
 /*         Disabled since ADLClientBW requires 2x multiplier for BW on top
@@ -2976,6 +2980,7 @@ bool PCM::isCPUModelSupported(const int model_)
             || model_ == TGL
             || model_ == ADL
             || model_ == RPL
+            || model_ == MTL
             || model_ == SKX
             || model_ == ICX
             || model_ == SPR
@@ -3146,7 +3151,7 @@ PCM::ErrorCode PCM::program(const PCM::ProgramMode mode_, const void * parameter
         canUsePerf = false;
         if (!silent) std::cerr << "Installed Linux kernel perf does not support hardware top-down level-1 counters. Using direct PMU programming instead.\n";
     }
-    if (canUsePerf && (cpu_model == ADL || cpu_model == RPL))
+    if (canUsePerf && (cpu_model == ADL || cpu_model == RPL || cpu_model == MTL))
     {
         canUsePerf = false;
         if (!silent) std::cerr << "Linux kernel perf rejects an architectural event on your platform. Using direct PMU programming instead.\n";
@@ -3232,6 +3237,7 @@ PCM::ErrorCode PCM::program(const PCM::ProgramMode mode_, const void * parameter
         switch ( cpu_model ) {
             case ADL:
             case RPL:
+            case MTL:
                 LLCArchEventInit(hybridAtomEventDesc);
                 hybridAtomEventDesc[2].event_number = SKL_MEM_LOAD_RETIRED_L2_MISS_EVTNR;
                 hybridAtomEventDesc[2].umask_value = SKL_MEM_LOAD_RETIRED_L2_MISS_UMASK;
@@ -4544,6 +4550,8 @@ const char * PCM::getUArchCodename(const int32 cpu_model_param) const
             return "Alder Lake";
         case RPL:
             return "Raptor Lake";
+        case MTL:
+            return "Meteor Lake";
         case SKX:
             if (cpu_model_param >= 0)
             {
diff --git a/src/cpucounters.h b/src/cpucounters.h
index 764b4dc0..b5b8def6 100644
--- a/src/cpucounters.h
+++ b/src/cpucounters.h
@@ -1554,6 +1554,7 @@ class PCM_API PCM
             {
             case ADL:
             case RPL:
+            case MTL:
                 if (topology[coreID].core_type == TopologyEntry::Atom)
                 {
                     return std::make_pair(OFFCORE_RESPONSE_0_EVTNR, event + 1);
@@ -1568,6 +1569,7 @@ class PCM_API PCM
        case EMR:
        case ADL: // ADL big core (GLC)
        case RPL:
+       case MTL:
            useGLCOCREvent = true;
            break;
        }
@@ -1792,6 +1794,7 @@ class PCM_API PCM
         RPL_1 = 0xba,
         RPL_2 = 0xbf,
         RPL_3 = 0xbe,
+        MTL = 0xAA,
         BDX = 79,
         KNL = 87,
         SKL = 94,
@@ -2005,6 +2008,7 @@ class PCM_API PCM
         {
         case ADL:
         case RPL:
+        case MTL:
             return 6;
         case SNOWRIDGE:
             return 4;
@@ -2342,6 +2346,7 @@ class PCM_API PCM
                  || cpu_model == PCM::ICX
                  || cpu_model == PCM::ADL
                  || cpu_model == PCM::RPL
+                 || cpu_model == PCM::MTL
                  || cpu_model == PCM::SPR
                  || cpu_model == PCM::EMR
                );
@@ -2613,6 +2618,7 @@ class PCM_API PCM
             || cpu_model == BROADWELL
             || cpu_model == ADL
             || cpu_model == RPL
+            || cpu_model == MTL
             || useSKLPath()
             ;
     }
@@ -4015,7 +4021,12 @@ uint64 getL2CacheMisses(const CounterStateType & before, const CounterStateType
     auto pcm = PCM::getInstance();
     if (pcm->isL2CacheMissesAvailable() == false) return 0ULL;
     const auto cpu_model = pcm->getCPUModel();
-    if (pcm->useSkylakeEvents() || cpu_model == PCM::SNOWRIDGE || cpu_model == PCM::ADL || cpu_model == PCM::RPL) {
+    if (pcm->useSkylakeEvents()
+        || cpu_model == PCM::SNOWRIDGE
+        || cpu_model == PCM::ADL
+        || cpu_model == PCM::RPL
+        || cpu_model == PCM::MTL
+        ) {
         return after.Event[BasicCounterState::SKLL2MissPos] - before.Event[BasicCounterState::SKLL2MissPos];
     }
     else if (pcm->isAtom() || cpu_model == PCM::KNL)
@@ -4121,7 +4132,11 @@ uint64 getL3CacheHitsSnoop(const CounterStateType & before, const CounterStateTy
     auto pcm = PCM::getInstance();
     if (!pcm->isL3CacheHitsSnoopAvailable()) return 0;
     const auto cpu_model = pcm->getCPUModel();
-    if (cpu_model == PCM::SNOWRIDGE || cpu_model == PCM::ADL || cpu_model == PCM::RPL)
+    if (cpu_model == PCM::SNOWRIDGE
+        || cpu_model == PCM::ADL
+        || cpu_model == PCM::RPL
+        || cpu_model == PCM::MTL
+        )
     {
         const int64 misses = getL3CacheMisses(before, after);
         const int64 refs = after.Event[BasicCounterState::ArchLLCRefPos] - before.Event[BasicCounterState::ArchLLCRefPos];

From 0dfed0ca3caee605ede12223ed3ebb6ac0b17953 Mon Sep 17 00:00:00 2001
From: Roman Dementiev <roman.dementiev@intel.com>
Date: Wed, 3 Apr 2024 17:43:21 +0200
Subject: [PATCH 07/22] add IRP and IIO PMUs for BDX

---
 src/cpucounters.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++
 src/cpucounters.h   |  4 ++++
 2 files changed, 50 insertions(+)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index 0f3235fc..d121dd91 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -2456,6 +2456,47 @@ void PCM::initUncorePMUsDirect()
             }
         }
     }
+    auto findPCICFGPMU = [](uint32 did,
+                            const int s,
+                            const uint32 CtlOffset,
+                            const std::vector<uint32> & CounterControlOffsets,
+                            const std::vector<uint32> & CounterValueOffsets)
+    {
+        int found = 0;
+        UncorePMU out;
+        forAllIntelDevices([&](const uint32 group, const uint32 bus, const uint32 device, const uint32 function, const uint32 device_id)
+        {
+            if (device_id == did)
+            {
+                if (s == found)
+                {
+                    auto handle = std::make_shared<PciHandleType>(group, bus, device, function);
+                    const size_t n_regs = 4;
+                    std::vector<std::shared_ptr<HWRegister> > CounterControlRegs, CounterValueRegs;
+                    for (size_t r = 0; r < n_regs; ++r)
+                    {
+                        CounterControlRegs.push_back(std::make_shared<PCICFGRegister32>(handle, CounterControlOffsets[r]));
+                        CounterValueRegs.push_back(std::make_shared<PCICFGRegister64>(handle, CounterValueOffsets[r]));
+                    }
+                    auto boxCtlRegister = std::make_shared<PCICFGRegister32>(handle, CtlOffset);
+                    out = UncorePMU(boxCtlRegister, CounterControlRegs, CounterValueRegs);
+                    return;
+                }
+                ++found;
+            }
+        });
+        return out;
+    };
+    for (uint32 s = 0; s < (uint32)num_sockets; ++s)
+    {
+        switch (cpu_model)
+        {
+            case BDX:
+                irpPMUs[s][0] = findPCICFGPMU(0x6f2a, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xB0, 0xB8, 0xC0});
+                iioPMUs[s][0] = findPCICFGPMU(0x6f34, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xA8, 0xB0, 0xB8});
+                break;
+        }
+    }
 
     if (hasPCICFGUncore() && MSR.size())
     {
@@ -9329,6 +9370,9 @@ void PCM::programIIOCounters(uint64 rawEvents[4], int IIOStack)
         case PCM::SNOWRIDGE:
             stacks_count = SNR_IIO_STACK_COUNT;
             break;
+        case PCM::BDX:
+            stacks_count = BDX_IIO_STACK_COUNT;
+            break;
         case PCM::SKX:
         default:
             stacks_count = SKX_IIO_STACK_COUNT;
@@ -9364,6 +9408,7 @@ void PCM::programIIOCounters(uint64 rawEvents[4], int IIOStack)
 
 void PCM::programIRPCounters(uint64 rawEvents[4], int IIOStack)
 {
+    // std::cerr << "PCM::programIRPCounters IRP PMU unit (stack) " << IIOStack << " getMaxNumOfIIOStacks(): " << getMaxNumOfIIOStacks()<< "\n";
     std::vector<int32> IIO_units;
     if (IIOStack == -1)
     {
@@ -9389,6 +9434,7 @@ void PCM::programIRPCounters(uint64 rawEvents[4], int IIOStack)
                 std::cerr << "IRP PMU unit (stack) " << unit << " is not found \n";
                 continue;
             }
+            // std::cerr << "Programming IRP PMU unit (stack) " << unit << " on socket " << i << " \n";
             auto& pmu = irpPMUs[i][unit];
             pmu.initFreeze(UNC_PMON_UNIT_CTL_RSV);
 
diff --git a/src/cpucounters.h b/src/cpucounters.h
index b5b8def6..9db4d5b7 100644
--- a/src/cpucounters.h
+++ b/src/cpucounters.h
@@ -981,6 +981,10 @@ class PCM_API PCM
         SNR_IIO_STACK_COUNT = 5
     };
 
+    enum BDXIIOStacks {
+        BDX_IIO_STACK_COUNT = 1
+    };
+
     enum IDX_IP
     {
         IDX_IAA = 0,

From 933755bbc53aa586f8725eb96912f6891af2a9ba Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Wed, 3 Apr 2024 18:22:10 +0200
Subject: [PATCH 08/22] disable BDX IRP and IIO PMU

Change-Id: If95d0b7d7e628ac77ed8d3651909c5c38055cf61
---
 src/cpucounters.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index d121dd91..f417d5f2 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -2456,7 +2456,7 @@ void PCM::initUncorePMUsDirect()
             }
         }
     }
-    auto findPCICFGPMU = [](uint32 did,
+    auto findPCICFGPMU = [](const uint32 did,
                             const int s,
                             const uint32 CtlOffset,
                             const std::vector<uint32> & CounterControlOffsets,
@@ -2491,10 +2491,12 @@ void PCM::initUncorePMUsDirect()
     {
         switch (cpu_model)
         {
+#if 0
             case BDX:
                 irpPMUs[s][0] = findPCICFGPMU(0x6f2a, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xB0, 0xB8, 0xC0});
                 iioPMUs[s][0] = findPCICFGPMU(0x6f34, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xA8, 0xB0, 0xB8});
                 break;
+#endif
         }
     }
 

From d41eb5a0525aa1246d505e149fc37d7cae6fd2e7 Mon Sep 17 00:00:00 2001
From: Roman Dementiev <roman.dementiev@intel.com>
Date: Thu, 4 Apr 2024 11:14:07 +0200
Subject: [PATCH 09/22] fix device scan for IRP/IIO

---
 src/cpucounters.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index f417d5f2..c85bb890 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -2479,8 +2479,8 @@ void PCM::initUncorePMUsDirect()
                         CounterValueRegs.push_back(std::make_shared<PCICFGRegister64>(handle, CounterValueOffsets[r]));
                     }
                     auto boxCtlRegister = std::make_shared<PCICFGRegister32>(handle, CtlOffset);
+                    // std::cerr << "socket " << std::hex <<  s <<  " device " << device_id << " " << group << ":" << bus << ":" << device << "@" << function << "\n" << std::dec;
                     out = UncorePMU(boxCtlRegister, CounterControlRegs, CounterValueRegs);
-                    return;
                 }
                 ++found;
             }

From 7b7fb7c5984b3d116b27ac95aa12095092900a41 Mon Sep 17 00:00:00 2001
From: gangdeng-intel <gang.deng@intel.com>
Date: Tue, 2 Apr 2024 16:36:50 +0800
Subject: [PATCH 10/22] For issue#547: add support QAT in-tree driver

---
 src/cpucounters.cpp | 44 +++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index c85bb890..527ce5ea 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -921,6 +921,7 @@ class QATTelemetryVirtualGeneralConfigRegister : public HWRegister
         operation = PCM::IDX_OPERATION(val);
 #ifdef __linux__
         std::ostringstream sysfs_path(std::ostringstream::out);
+	std::string telemetry_filename;
         switch (operation)
         {
             case PCM::QAT_TLM_START: //enable
@@ -936,6 +937,18 @@ class QATTelemetryVirtualGeneralConfigRegister : public HWRegister
                         std::hex << std::setw(2) << std::setfill('0') << d << "." <<
                         std::hex << f << "/telemetry/control";
 
+                    /*check telemetry for out-of tree driver*/
+                    telemetry_filename = readSysFS(sysfs_path.str().c_str(), true);
+                    if(!telemetry_filename.size()){
+                        /*is not oot driver, check telemetry for in tree driver  (since kernel 6.8)*/
+                        sysfs_path.str("");
+                        sysfs_path << std::string("/sys/kernel/debug/qat_4xxx_") <<
+                            std::hex << std::setw(4) << std::setfill('0') << domain << ":" <<
+                            std::hex << std::setw(2) << std::setfill('0') << b << ":" <<
+                            std::hex << std::setw(2) << std::setfill('0') << d << "." <<
+                            std::hex << f << "/telemetry/control";
+                    }
+
                     if (writeSysFS(sysfs_path.str().c_str(), (operation == PCM::QAT_TLM_START  ? "1" : "0")) == false)
                     {
                         std::cerr << "Linux sysfs: Error on control QAT telemetry operation = " << operation << ".\n";
@@ -951,7 +964,17 @@ class QATTelemetryVirtualGeneralConfigRegister : public HWRegister
                         std::hex << std::setw(2) << std::setfill('0') << b << ":" <<
                         std::hex << std::setw(2) << std::setfill('0') << d << "." <<
                         std::hex << f << "/telemetry/device_data";
-
+                    /*check telemetry for out-of tree driver*/
+                    telemetry_filename = readSysFS(sysfs_path.str().c_str(), true);
+                    if(!telemetry_filename.size()){
+                        /*is not oot driver, check telemetry for in tree driver  (since kernel 6.8)*/
+                        sysfs_path.str("");
+                        sysfs_path << std::string("/sys/kernel/debug/qat_4xxx_") <<
+                            std::hex << std::setw(4) << std::setfill('0') << domain << ":" <<
+                            std::hex << std::setw(2) << std::setfill('0') << b << ":" <<
+                            std::hex << std::setw(2) << std::setfill('0') << d << "." <<
+                            std::hex << f << "/telemetry/device_data";
+                    }
                     data_cache.clear();
                     readMapFromSysFS(sysfs_path.str().c_str(), data_cache);
                 }
@@ -2382,17 +2405,28 @@ void PCM::initUncorePMUsDirect()
             for (auto & devInfo : devInfos)
             {
                 std::ostringstream qat_TLMCTL_sysfs_path(std::ostringstream::out);
+				/*parse telemetry follow rule of out of tree driver*/
                 qat_TLMCTL_sysfs_path << std::string("/sys/bus/pci/devices/") <<
                     std::hex << std::setw(4) << std::setfill('0') << devInfo.domain << ":" <<
                     std::hex << std::setw(2) << std::setfill('0') << devInfo.bus << ":" <<
                     std::hex << std::setw(2) << std::setfill('0') << devInfo.dev << "." <<
                     std::hex << devInfo.func << "/telemetry/control";
-                const std::string qatTLMCTLStr = readSysFS(qat_TLMCTL_sysfs_path.str().c_str(), true);
+                    std::string qatTLMCTLStr = readSysFS(qat_TLMCTL_sysfs_path.str().c_str(), true);
                 if (!qatTLMCTLStr.size()) //check TLM feature available or NOT.
                 {
-                    std::cout << "Warning: IDX - QAT telemetry feature of B:0x" << std::hex << devInfo.bus << ",D:0x" << devInfo.dev << ",F:0x" << devInfo.func \
-                        << " is NOT available, skipped." << std::dec << std::endl;
-                    continue;
+                    qat_TLMCTL_sysfs_path.str("");
+                    /*parse telemetry follow rule of in tree driver*/
+                    qat_TLMCTL_sysfs_path << std::string("/sys/kernel/debug/qat_4xxx_") <<
+                        std::hex << std::setw(4) << std::setfill('0') << devInfo.domain << ":" <<
+                        std::hex << std::setw(2) << std::setfill('0') << devInfo.bus << ":" <<
+                        std::hex << std::setw(2) << std::setfill('0') << devInfo.dev << "." <<
+                        std::hex << devInfo.func << "/telemetry/control";                    
+                    qatTLMCTLStr = readSysFS(qat_TLMCTL_sysfs_path.str().c_str(), true);
+		    if(!qatTLMCTLStr.size()){
+                        std::cout << "Warning: IDX - QAT telemetry feature of B:0x" << std::hex << devInfo.bus << ",D:0x" << devInfo.dev << ",F:0x" << devInfo.func \
+                            << " is NOT available, skipped." << std::dec << std::endl;
+	                continue;
+		    }
                 }
                 idxPMUs[IDX_QAT].push_back(createQATPMU(devInfo.numa_node, devInfo.socket_id, devInfo.domain , devInfo.bus, devInfo.dev , devInfo.func));
             }

From 9fecec645352f0053707ae79e25fbf6f3c65b5e0 Mon Sep 17 00:00:00 2001
From: gangdeng-intel <gang.deng@intel.com>
Date: Sun, 7 Apr 2024 16:30:38 +0800
Subject: [PATCH 11/22] For issue#547: remove spaces for code alignment

---
 src/cpucounters.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index 527ce5ea..11eeac68 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -921,7 +921,7 @@ class QATTelemetryVirtualGeneralConfigRegister : public HWRegister
         operation = PCM::IDX_OPERATION(val);
 #ifdef __linux__
         std::ostringstream sysfs_path(std::ostringstream::out);
-	std::string telemetry_filename;
+        std::string telemetry_filename;
         switch (operation)
         {
             case PCM::QAT_TLM_START: //enable
@@ -2405,13 +2405,13 @@ void PCM::initUncorePMUsDirect()
             for (auto & devInfo : devInfos)
             {
                 std::ostringstream qat_TLMCTL_sysfs_path(std::ostringstream::out);
-				/*parse telemetry follow rule of out of tree driver*/
+                /*parse telemetry follow rule of out of tree driver*/
                 qat_TLMCTL_sysfs_path << std::string("/sys/bus/pci/devices/") <<
                     std::hex << std::setw(4) << std::setfill('0') << devInfo.domain << ":" <<
                     std::hex << std::setw(2) << std::setfill('0') << devInfo.bus << ":" <<
                     std::hex << std::setw(2) << std::setfill('0') << devInfo.dev << "." <<
                     std::hex << devInfo.func << "/telemetry/control";
-                    std::string qatTLMCTLStr = readSysFS(qat_TLMCTL_sysfs_path.str().c_str(), true);
+                std::string qatTLMCTLStr = readSysFS(qat_TLMCTL_sysfs_path.str().c_str(), true);
                 if (!qatTLMCTLStr.size()) //check TLM feature available or NOT.
                 {
                     qat_TLMCTL_sysfs_path.str("");
@@ -2422,11 +2422,11 @@ void PCM::initUncorePMUsDirect()
                         std::hex << std::setw(2) << std::setfill('0') << devInfo.dev << "." <<
                         std::hex << devInfo.func << "/telemetry/control";                    
                     qatTLMCTLStr = readSysFS(qat_TLMCTL_sysfs_path.str().c_str(), true);
-		    if(!qatTLMCTLStr.size()){
+                    if(!qatTLMCTLStr.size()){
                         std::cout << "Warning: IDX - QAT telemetry feature of B:0x" << std::hex << devInfo.bus << ",D:0x" << devInfo.dev << ",F:0x" << devInfo.func \
                             << " is NOT available, skipped." << std::dec << std::endl;
-	                continue;
-		    }
+                        continue;
+                    }
                 }
                 idxPMUs[IDX_QAT].push_back(createQATPMU(devInfo.numa_node, devInfo.socket_id, devInfo.domain , devInfo.bus, devInfo.dev , devInfo.func));
             }

From d4586f044b33b2eb912495723e1dad0f0b36e507 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Mon, 8 Apr 2024 10:49:53 +0200
Subject: [PATCH 12/22] get rid of a compile warning

Change-Id: I58c0a9419946c4393399cde40de268bcc1040416
---
 src/cpucounters.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index 11eeac68..23c265f5 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -2490,6 +2490,7 @@ void PCM::initUncorePMUsDirect()
             }
         }
     }
+#if 0
     auto findPCICFGPMU = [](const uint32 did,
                             const int s,
                             const uint32 CtlOffset,
@@ -2525,14 +2526,13 @@ void PCM::initUncorePMUsDirect()
     {
         switch (cpu_model)
         {
-#if 0
             case BDX:
                 irpPMUs[s][0] = findPCICFGPMU(0x6f2a, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xB0, 0xB8, 0xC0});
                 iioPMUs[s][0] = findPCICFGPMU(0x6f34, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xA8, 0xB0, 0xB8});
                 break;
-#endif
         }
     }
+#endif
 
     if (hasPCICFGUncore() && MSR.size())
     {

From 10c16e9fa743deb5740473f7f7bee9ae4785539b Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Mon, 8 Apr 2024 19:01:18 +0200
Subject: [PATCH 13/22] change IRP device ID

Change-Id: Idd8c2203c5342919278d987d7017a1152731c249
from: https://github.com/torvalds/linux/blob/026e680b0a08a62b1d948e5a8ca78700bfac0e6e/arch/x86/events/intel/uncore_snbep.c#L3465
---
 src/cpucounters.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp
index 23c265f5..f441538c 100644
--- a/src/cpucounters.cpp
+++ b/src/cpucounters.cpp
@@ -2527,7 +2527,7 @@ void PCM::initUncorePMUsDirect()
         switch (cpu_model)
         {
             case BDX:
-                irpPMUs[s][0] = findPCICFGPMU(0x6f2a, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xB0, 0xB8, 0xC0});
+                irpPMUs[s][0] = findPCICFGPMU(0x6f39, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xB0, 0xB8, 0xC0});
                 iioPMUs[s][0] = findPCICFGPMU(0x6f34, s, 0xF4, {0xD8, 0xDC, 0xE0, 0xE4}, {0xA0, 0xA8, 0xB0, 0xB8});
                 break;
         }

From 8756f703d878a0ea74cee504102c0ae2dd0a8629 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 8 Apr 2024 10:39:37 +0000
Subject: [PATCH 14/22] Bump github/codeql-action from 3.24.5 to 3.24.10

Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.5 to 3.24.10.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/47b3d888fe66b639e431abf22ebca059152f1eea...4355270be187e1b672a7a1c7c7bae5afdc1ab94a)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
---
 .github/workflows/codeql.yml    | 6 +++---
 .github/workflows/scorecard.yml | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 88e252d9..57d12c32 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -50,7 +50,7 @@ jobs:
 
       # Initializes the CodeQL tools for scanning.
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
+        uses: github/codeql-action/init@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
         with:
           languages: ${{ matrix.language }}
           # If you wish to specify custom queries, you can do so here or in a config file.
@@ -60,7 +60,7 @@ jobs:
       # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
       # If this step fails, then you should remove it and run the build manually (see below)
       - name: Autobuild
-        uses: github/codeql-action/autobuild@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
+        uses: github/codeql-action/autobuild@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
 
       # â„šī¸ Command-line programs to run using the OS shell.
       # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -73,6 +73,6 @@ jobs:
       #   ./location_of_script_within_repo/buildscript.sh
 
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
+        uses: github/codeql-action/analyze@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
         with:
           category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index 8aea12fe..f8ef1970 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -73,6 +73,6 @@ jobs:
 
       # Upload the results to GitHub's code scanning dashboard.
       - name: "Upload to code-scanning"
-        uses: github/codeql-action/upload-sarif@47b3d888fe66b639e431abf22ebca059152f1eea # v3.24.5
+        uses: github/codeql-action/upload-sarif@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
         with:
           sarif_file: results.sarif

From 543570e1fdd3b7255aa699f67ffc35e5fdccfd75 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 09:56:23 +0200
Subject: [PATCH 15/22] add error checking to start.sh

Change-Id: Ia01a500ab97b789f8ca0caba709bf644f6344f7b
---
 scripts/grafana/start.sh | 40 +++++++++++++++++++---------------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/scripts/grafana/start.sh b/scripts/grafana/start.sh
index 060b6124..b89c60da 100755
--- a/scripts/grafana/start.sh
+++ b/scripts/grafana/start.sh
@@ -1,5 +1,7 @@
 #!/bin/sh
 
+set -e
+
 if [ "$#" -ne 1 ];
 then
   echo
@@ -9,49 +11,45 @@ then
   exit 1
 fi
 
+mkdir -p grafana_volume/dashboards || { echo "Error creating grafana_volume/dashboards directory"; exit 1; }
+mkdir -p influxdb_volume || { echo "Error creating influxdb_volume directory"; exit 1; }
 
-mkdir -p grafana_volume/dashboards
-mkdir -p influxdb_volume
-
-chmod -R 777 *_volume
-
-mkdir -p provisioning/datasources
-cp automatic_influxdb.yml provisioning/datasources/automatic.yml
+chmod -R 777 *_volume || { echo "Error setting permissions on volume directories"; exit 1; }
 
+mkdir -p provisioning/datasources || { echo "Error creating provisioning/datasources directory"; exit 1; }
+cp automatic_influxdb.yml provisioning/datasources/automatic.yml || { echo "Error copying automatic_influxdb.yml"; exit 1; }
 
 CTR_RUN=${CTR_RUN:-docker}
 
 # check if argument is file, create the telegraf.conf accordingly
 if [ -f "$1" ]; then
   echo "creating telegraf.conf for hosts in targets file";
-  head -n -7 "telegraf.conf.template" > telegraf.conf
+  head -n -7 "telegraf.conf.template" > telegraf.conf || { echo "Error creating telegraf.conf"; exit 1; }
   while IFS='' read -r line || [[ -n "$line" ]]; do
     # Split the line at the : character to get the IP and port
     ip=$(echo "$line" | cut -d ':' -f 1)
     port=$(echo "$line" | cut -d ':' -f 2)
     # Append the transformed line to the output file, separated by a comma
     echo -n "\"http://$ip:$port/persecond/\"," >> telegraf.conf
-  done < $1
-  sed -i '$ s/,$//' telegraf.conf
-  tail -n -6 "telegraf.conf.template" >> telegraf.conf
+  done < "$1"
+  sed -i '$ s/,$//' telegraf.conf || { echo "Error editing telegraf.conf"; exit 1; }
+  tail -n -6 "telegraf.conf.template" >> telegraf.conf || { echo "Error appending to telegraf.conf"; exit 1; }
   echo Downloading PCM dashboard
-  curl -o grafana_volume/dashboards/pcm-dashboard.json $(head -1 $1)/dashboard
-
+  curl -o grafana_volume/dashboards/pcm-dashboard.json $(head -1 "$1")/dashboard || { echo "Error downloading PCM dashboard"; exit 1; }
 else
   echo "creating telegraf.conf for $1 ";
-  sed "s#PCMSENSORSERVER#$1#g" telegraf.conf.template > telegraf.conf
+  sed "s#PCMSENSORSERVER#$1#g" telegraf.conf.template > telegraf.conf || { echo "Error creating telegraf.conf"; exit 1; }
   echo Downloading PCM dashboard
-  curl -o grafana_volume/dashboards/pcm-dashboard.json $1/dashboard
+  curl -o grafana_volume/dashboards/pcm-dashboard.json "$1"/dashboard || { echo "Error downloading PCM dashboard"; exit 1; }
 fi
 
 echo "Creating influxdb network"
-${CTR_RUN} network create influxdb-network
+${CTR_RUN} network create influxdb-network || { echo "Error creating influxdb network"; exit 1; }
 echo Starting influxdb
-${CTR_RUN} run -d --name influxdb -p 8083:8083 -p 8086:8086 --network=influxdb-network -v $PWD/influxdb_volume:/var/lib/influxdb influxdb:1.8.0-alpine
+${CTR_RUN} run -d --name influxdb -p 8083:8083 -p 8086:8086 --network=influxdb-network -v "$PWD"/influxdb_volume:/var/lib/influxdb influxdb:1.8.0-alpine || { echo "Error starting influxdb"; exit 1; }
 echo Starting telegraf
-${CTR_RUN} run -d --name telegraf --network=influxdb-network -v $PWD/telegraf.conf:/etc/telegraf/telegraf.conf:ro telegraf
+${CTR_RUN} run -d --name telegraf --network=influxdb-network -v "$PWD"/telegraf.conf:/etc/telegraf/telegraf.conf:ro telegraf || { echo "Error starting telegraf"; exit 1; }
 echo Starting grafana
-${CTR_RUN} run -d --network=influxdb-network --name grafana -p 3000:3000 -v $PWD/provisioning:/etc/grafana/provisioning -v $PWD/grafana_volume:/var/lib/grafana grafana/grafana
-
-echo Start browser at http://localhost:3000/ and login with admin user, password admin
+${CTR_RUN} run -d --network=influxdb-network --name grafana -p 3000:3000 -v "$PWD"/provisioning:/etc/grafana/provisioning -v "$PWD"/grafana_volume:/var/lib/grafana grafana/grafana || { echo "Error starting grafana"; exit 1; }
 
+echo "Start browser at http://localhost:3000/ and login with admin user, password admin"

From e8ecebc07f4ebaa9aef777a5eb2454d1cc1abf12 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 10:01:11 +0200
Subject: [PATCH 16/22] factor out the usage printing

Change-Id: I0ebaab826b1652f9b859727d5f1b310d9ec87ef1
---
 scripts/grafana/start.sh | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/scripts/grafana/start.sh b/scripts/grafana/start.sh
index b89c60da..52bca6ec 100755
--- a/scripts/grafana/start.sh
+++ b/scripts/grafana/start.sh
@@ -2,13 +2,16 @@
 
 set -e
 
-if [ "$#" -ne 1 ];
-then
+usage() {
   echo
   echo "Usage: $0 http(s)://target_address:port"
   echo
   echo "target_address is the hostname or IP address of the system that runs pcm-sensor-server"
   exit 1
+}
+
+if [ "$#" -ne 1 ]; then
+  usage
 fi
 
 mkdir -p grafana_volume/dashboards || { echo "Error creating grafana_volume/dashboards directory"; exit 1; }

From 3146e3242c8aafe6ed14573806ec377d986e11b0 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 10:11:38 +0200
Subject: [PATCH 17/22] add URL validation

Change-Id: I4b70f14bc5e63487d75f4b1751e2f2c1d49f31ef
---
 scripts/grafana/start.sh | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/scripts/grafana/start.sh b/scripts/grafana/start.sh
index 52bca6ec..9ecd122a 100755
--- a/scripts/grafana/start.sh
+++ b/scripts/grafana/start.sh
@@ -10,10 +10,22 @@ usage() {
   exit 1
 }
 
+# Validate the URL format
+validate_url() {
+  local url=$1
+  local regex='^https?://([a-zA-Z0-9.-]+):[0-9]+$'
+  if ! [[ $url =~ $regex ]]; then
+    echo "Error: The URL provided is not in the correct format."
+    usage
+  fi
+}
+
 if [ "$#" -ne 1 ]; then
   usage
 fi
 
+validate_url "$1"
+
 mkdir -p grafana_volume/dashboards || { echo "Error creating grafana_volume/dashboards directory"; exit 1; }
 mkdir -p influxdb_volume || { echo "Error creating influxdb_volume directory"; exit 1; }
 

From ee52e3733bbce6d4c97f37ef9c9f04f0d675fb14 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 10:17:15 +0200
Subject: [PATCH 18/22] don't accept localhost

Change-Id: If45fa90daa7acc1f2772cd09921deff004f5c403
---
 scripts/grafana/start.sh | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/scripts/grafana/start.sh b/scripts/grafana/start.sh
index 9ecd122a..7d305fd8 100755
--- a/scripts/grafana/start.sh
+++ b/scripts/grafana/start.sh
@@ -10,14 +10,21 @@ usage() {
   exit 1
 }
 
-# Validate the URL format
+# Validate the URL format and reject localhost or 127.0.0.1
 validate_url() {
   local url=$1
   local regex='^https?://([a-zA-Z0-9.-]+):[0-9]+$'
+  local localhost_regex='^(https?://)?(localhost|127\.0\.0\.1):[0-9]+$'
+
   if ! [[ $url =~ $regex ]]; then
     echo "Error: The URL provided is not in the correct format."
     usage
   fi
+
+  if [[ $url =~ $localhost_regex ]]; then
+    echo "Error: The target_address cannot be localhost or 127.0.0.1."
+    usage
+  fi
 }
 
 if [ "$#" -ne 1 ]; then

From 00e31bd4ddb90f05bc8793280885046fc0a0cab5 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 10:39:35 +0200
Subject: [PATCH 19/22] add error checking and validation to
 start-prometheus.sh

Change-Id: I7f50be73dc2744580b61b88b5c92f524254ffb54
---
 scripts/grafana/start-prometheus.sh | 62 ++++++++++++++++++++---------
 1 file changed, 43 insertions(+), 19 deletions(-)

diff --git a/scripts/grafana/start-prometheus.sh b/scripts/grafana/start-prometheus.sh
index 849cb084..303b7214 100755
--- a/scripts/grafana/start-prometheus.sh
+++ b/scripts/grafana/start-prometheus.sh
@@ -1,49 +1,73 @@
 #!/bin/sh
 
-if [ "$#" -ne 1 ];
-then
+set -e
+
+usage() {
   echo
   echo "Usage: $0 target_address:port"
   echo
   echo "target_address is the hostname or IP address of the system that runs pcm-sensor-server"
+  echo
+  echo "Alternative usage: $0 filename"
+  echo
+  echo "Specify filename containing target_address:port in each line"
   exit 1
-fi
+}
 
-CTR_RUN=${CTR_RUN:-docker}
+# Validate the URL format and reject localhost or 127.0.0.1
+validate_url() {
+  local url=$1
+  local regex='^([a-zA-Z0-9.-]+):[0-9]+$'
+  local localhost_regex='^(localhost|127\.0\.0\.1):[0-9]+$'
 
-mkdir -p grafana_volume/dashboards
-mkdir -p prometheus_volume
+  if ! [[ $url =~ $regex ]]; then
+    echo "Error: The target_address ($url) provided is not in the correct format."
+    usage
+  fi
 
-chmod -R 777 *_volume
+  if [[ $url =~ $localhost_regex ]]; then
+    echo "Error: The target_address cannot be localhost or 127.0.0.1."
+    usage
+  fi
+}
 
-mkdir -p provisioning/datasources
-cp automatic_prometheus.yml provisioning/datasources/automatic.yml
+if [ "$#" -ne 1 ]; then
+  usage
+fi
 
+CTR_RUN=${CTR_RUN:-docker}
+
+mkdir -p grafana_volume/dashboards || { echo "Error creating grafana_volume/dashboards directory"; exit 1; }
+mkdir -p prometheus_volume || { echo "Error creating prometheus_volume directory"; exit 1; }
+
+chmod -R 777 *_volume || { echo "Error setting permissions on volume directories"; exit 1; }
 
+mkdir -p provisioning/datasources || { echo "Error creating provisioning/datasources directory"; exit 1; }
+cp automatic_prometheus.yml provisioning/datasources/automatic.yml || { echo "Error copying automatic_prometheus.yml"; exit 1; }
 
 # check if argument is file, create the prometheus.yml accordingly
 if [ -f "$1" ]; then
   echo "creating prometheus.yml for hosts in targets file";
-  head -n -1 "prometheus.yml.template" > prometheus.yml
+  head -n -1 "prometheus.yml.template" > prometheus.yml || { echo "Error creating prometheus.yml"; exit 1; }
   while read -r line; do
+    validate_url "$line"
     echo "    - targets: ['$line']" >> "prometheus.yml"
   done < "$1"
   echo Downloading PCM dashboard
-  curl -o grafana_volume/dashboards/pcm-dashboard.json $(head -1 $1)/dashboard/prometheus
-
+  curl -o grafana_volume/dashboards/pcm-dashboard.json $(head -1 "$1")/dashboard/prometheus || { echo "Error downloading PCM dashboard"; exit 1; }
 else
+  validate_url "$1"
   echo "creating prometheus.yml for $1 ";
-  sed "s#PCMSENSORSERVER#$1#g" prometheus.yml.template > prometheus.yml
+  sed "s#PCMSENSORSERVER#$1#g" prometheus.yml.template > prometheus.yml || { echo "Error creating prometheus.yml"; exit 1; }
   echo Downloading PCM dashboard
-  curl -o grafana_volume/dashboards/pcm-dashboard.json $1/dashboard/prometheus
+  curl -o grafana_volume/dashboards/pcm-dashboard.json "$1"/dashboard/prometheus || { echo "Error downloading PCM dashboard"; exit 1; }
 fi
 
 echo "Starting prometheus network"
-${CTR_RUN} network create prometheus-network
+${CTR_RUN} network create prometheus-network || { echo "Error creating prometheus network"; exit 1; }
 echo Starting prometheus
-${CTR_RUN} run --name prometheus --network=prometheus-network -d -p 9090:9090 -v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml:Z -v $PWD/prometheus_volume:/prometheus:Z quay.io/prometheus/prometheus:latest
+${CTR_RUN} run --name prometheus --network=prometheus-network -d -p 9090:9090 -v "$PWD"/prometheus.yml:/etc/prometheus/prometheus.yml:Z -v "$PWD"/prometheus_volume:/prometheus:Z quay.io/prometheus/prometheus:latest || { echo "Error starting prometheus"; exit 1; }
 echo Starting grafana
-${CTR_RUN} run -d --network=prometheus-network --name=grafana -p 3000:3000 -v $PWD/grafana_volume:/var/lib/grafana:Z -v $PWD/provisioning:/etc/grafana/provisioning:Z docker.io/grafana/grafana:latest
-
-echo Start browser at http://localhost:3000/ and login with admin user, password admin
+${CTR_RUN} run -d --network=prometheus-network --name=grafana -p 3000:3000 -v "$PWD"/grafana_volume:/var/lib/grafana:Z -v "$PWD"/provisioning:/etc/grafana/provisioning:Z docker.io/grafana/grafana:latest || { echo "Error starting grafana"; exit 1; }
 
+echo "Start browser at http://localhost:3000/ and login with admin user, password admin"

From 3a5509f760618c23dda9fffff821d64d5ece92b2 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 10:46:29 +0200
Subject: [PATCH 20/22] Do not error if the network does not exist

Change-Id: I97e48df03daad61c5b20ce3b2926edd7073c08ad
---
 scripts/grafana/stop.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/grafana/stop.sh b/scripts/grafana/stop.sh
index 2fc019c5..c561123b 100755
--- a/scripts/grafana/stop.sh
+++ b/scripts/grafana/stop.sh
@@ -10,5 +10,5 @@ for c in grafana telegraf influxdb prometheus; do
 	fi
 done
 
-${CTR_RUN} network rm prometheus-network influxdb-network
+${CTR_RUN} network rm --force prometheus-network influxdb-network
 

From 3b2c4ceb2490f6e7df70bbd58bc341384c8f3f83 Mon Sep 17 00:00:00 2001
From: "Dementiev, Roman" <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 11:05:32 +0200
Subject: [PATCH 21/22] Revert "Do not error if the network does not exist"

This reverts commit a409056a7b45df89248142c42ee27e4ebff38d1a.
---
 scripts/grafana/stop.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/grafana/stop.sh b/scripts/grafana/stop.sh
index c561123b..2fc019c5 100755
--- a/scripts/grafana/stop.sh
+++ b/scripts/grafana/stop.sh
@@ -10,5 +10,5 @@ for c in grafana telegraf influxdb prometheus; do
 	fi
 done
 
-${CTR_RUN} network rm --force prometheus-network influxdb-network
+${CTR_RUN} network rm prometheus-network influxdb-network
 

From 1bebbcbe16d3676ef6b4324b863f2c68d711eb03 Mon Sep 17 00:00:00 2001
From: Roman Dementiev <roman.dementiev@intel.com>
Date: Fri, 12 Apr 2024 11:26:36 +0200
Subject: [PATCH 22/22] enhance scripts

---
 scripts/grafana/clean.sh            | 4 ++++
 scripts/grafana/start-prometheus.sh | 2 +-
 scripts/grafana/start.sh            | 2 +-
 3 files changed, 6 insertions(+), 2 deletions(-)
 create mode 100644 scripts/grafana/clean.sh

diff --git a/scripts/grafana/clean.sh b/scripts/grafana/clean.sh
new file mode 100644
index 00000000..6032773e
--- /dev/null
+++ b/scripts/grafana/clean.sh
@@ -0,0 +1,4 @@
+
+
+rm -rf provisioning/datasources
+rm -rf *_volume
diff --git a/scripts/grafana/start-prometheus.sh b/scripts/grafana/start-prometheus.sh
index 303b7214..79e4e0d6 100755
--- a/scripts/grafana/start-prometheus.sh
+++ b/scripts/grafana/start-prometheus.sh
@@ -70,4 +70,4 @@ ${CTR_RUN} run --name prometheus --network=prometheus-network -d -p 9090:9090 -v
 echo Starting grafana
 ${CTR_RUN} run -d --network=prometheus-network --name=grafana -p 3000:3000 -v "$PWD"/grafana_volume:/var/lib/grafana:Z -v "$PWD"/provisioning:/etc/grafana/provisioning:Z docker.io/grafana/grafana:latest || { echo "Error starting grafana"; exit 1; }
 
-echo "Start browser at http://localhost:3000/ and login with admin user, password admin"
+echo "Start browser at http://"`hostname`":3000/ or http://localhost:3000/ and login with admin user, password admin"
diff --git a/scripts/grafana/start.sh b/scripts/grafana/start.sh
index 7d305fd8..437094b5 100755
--- a/scripts/grafana/start.sh
+++ b/scripts/grafana/start.sh
@@ -74,4 +74,4 @@ ${CTR_RUN} run -d --name telegraf --network=influxdb-network -v "$PWD"/telegraf.
 echo Starting grafana
 ${CTR_RUN} run -d --network=influxdb-network --name grafana -p 3000:3000 -v "$PWD"/provisioning:/etc/grafana/provisioning -v "$PWD"/grafana_volume:/var/lib/grafana grafana/grafana || { echo "Error starting grafana"; exit 1; }
 
-echo "Start browser at http://localhost:3000/ and login with admin user, password admin"
+echo "Start browser at http://"`hostname`":3000/ or http://localhost:3000/ and login with admin user, password admin"