LCOV - code coverage report
Current view: top level - lib/power - power_intel_uncore.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 5 185 2.7 %
Date: 2024-01-22 15:35:40 Functions: 1 14 7.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 96 1.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2022 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <errno.h>
       6                 :            : #include <dirent.h>
       7                 :            : #include <fnmatch.h>
       8                 :            : 
       9                 :            : #include <rte_memcpy.h>
      10                 :            : 
      11                 :            : #include "power_intel_uncore.h"
      12                 :            : #include "power_common.h"
      13                 :            : 
      14                 :            : #define MAX_UNCORE_FREQS 32
      15                 :            : #define MAX_NUMA_DIE 8
      16                 :            : #define BUS_FREQ     100000
      17                 :            : #define FILTER_LENGTH 18
      18                 :            : #define PACKAGE_FILTER "package_%02u_die_*"
      19                 :            : #define DIE_FILTER "package_%02u_die_%02u"
      20                 :            : #define INTEL_UNCORE_FREQUENCY_DIR "/sys/devices/system/cpu/intel_uncore_frequency"
      21                 :            : #define POWER_GOVERNOR_PERF "performance"
      22                 :            : #define POWER_INTEL_UNCORE_SYSFILE_MAX_FREQ \
      23                 :            :                 "/sys/devices/system/cpu/intel_uncore_frequency/package_%02u_die_%02u/max_freq_khz"
      24                 :            : #define POWER_INTEL_UNCORE_SYSFILE_MIN_FREQ  \
      25                 :            :                 "/sys/devices/system/cpu/intel_uncore_frequency/package_%02u_die_%02u/min_freq_khz"
      26                 :            : #define POWER_INTEL_UNCORE_SYSFILE_BASE_MAX_FREQ \
      27                 :            :                 "/sys/devices/system/cpu/intel_uncore_frequency/package_%02u_die_%02u/initial_max_freq_khz"
      28                 :            : #define POWER_INTEL_UNCORE_SYSFILE_BASE_MIN_FREQ  \
      29                 :            :                 "/sys/devices/system/cpu/intel_uncore_frequency/package_%02u_die_%02u/initial_min_freq_khz"
      30                 :            : 
      31                 :            : 
      32                 :            : struct uncore_power_info {
      33                 :            :         unsigned int die;                  /* Core die id */
      34                 :            :         unsigned int pkg;                  /* Package id */
      35                 :            :         uint32_t freqs[MAX_UNCORE_FREQS];  /* Frequency array */
      36                 :            :         uint32_t nb_freqs;                 /* Number of available freqs */
      37                 :            :         FILE *f_cur_min;                   /* FD of scaling_min */
      38                 :            :         FILE *f_cur_max;                   /* FD of scaling_max */
      39                 :            :         uint32_t curr_idx;                 /* Freq index in freqs array */
      40                 :            :         uint32_t org_min_freq;             /* Original min freq of uncore */
      41                 :            :         uint32_t org_max_freq;             /* Original max freq of uncore */
      42                 :            :         uint32_t init_max_freq;            /* System max uncore freq */
      43                 :            :         uint32_t init_min_freq;            /* System min uncore freq */
      44                 :            : } __rte_cache_aligned;
      45                 :            : 
      46                 :            : static struct uncore_power_info uncore_info[RTE_MAX_NUMA_NODES][MAX_NUMA_DIE];
      47                 :            : 
      48                 :            : static int
      49                 :          0 : set_uncore_freq_internal(struct uncore_power_info *ui, uint32_t idx)
      50                 :            : {
      51                 :            :         uint32_t target_uncore_freq, curr_max_freq;
      52                 :            :         int ret;
      53                 :            : 
      54   [ #  #  #  # ]:          0 :         if (idx >= MAX_UNCORE_FREQS || idx >= ui->nb_freqs) {
      55                 :          0 :                 POWER_LOG(DEBUG, "Invalid uncore frequency index %u, which "
      56                 :            :                                 "should be less than %u", idx, ui->nb_freqs);
      57                 :          0 :                 return -1;
      58                 :            :         }
      59                 :            : 
      60                 :          0 :         target_uncore_freq = ui->freqs[idx];
      61                 :            : 
      62                 :            :         /* check current max freq, so that the value to be flushed first
      63                 :            :          * can be accurately recorded
      64                 :            :          */
      65                 :          0 :         open_core_sysfs_file(&ui->f_cur_max, "rw+", POWER_INTEL_UNCORE_SYSFILE_MAX_FREQ,
      66                 :            :                         ui->pkg, ui->die);
      67         [ #  # ]:          0 :         if (ui->f_cur_max == NULL) {
      68                 :          0 :                 POWER_LOG(DEBUG, "failed to open %s",
      69                 :            :                                 POWER_INTEL_UNCORE_SYSFILE_MAX_FREQ);
      70                 :          0 :                 return -1;
      71                 :            :         }
      72                 :          0 :         ret = read_core_sysfs_u32(ui->f_cur_max, &curr_max_freq);
      73         [ #  # ]:          0 :         if (ret < 0) {
      74                 :          0 :                 POWER_LOG(DEBUG, "Failed to read %s",
      75                 :            :                                 POWER_INTEL_UNCORE_SYSFILE_MAX_FREQ);
      76                 :          0 :                 fclose(ui->f_cur_max);
      77                 :          0 :                 return -1;
      78                 :            :         }
      79                 :            : 
      80                 :            :         /* check this value first before fprintf value to f_cur_max, so value isn't overwritten */
      81         [ #  # ]:          0 :         if (fprintf(ui->f_cur_min, "%u", target_uncore_freq) < 0) {
      82                 :          0 :                 POWER_LOG(ERR, "Fail to write new uncore frequency for "
      83                 :            :                                 "pkg %02u die %02u", ui->pkg, ui->die);
      84                 :          0 :                 return -1;
      85                 :            :         }
      86                 :            : 
      87         [ #  # ]:          0 :         if (fprintf(ui->f_cur_max, "%u", target_uncore_freq) < 0) {
      88                 :          0 :                 POWER_LOG(ERR, "Fail to write new uncore frequency for "
      89                 :            :                                 "pkg %02u die %02u", ui->pkg, ui->die);
      90                 :          0 :                 return -1;
      91                 :            :         }
      92                 :            : 
      93                 :            :         POWER_DEBUG_LOG("Uncore frequency '%u' to be set for pkg %02u die %02u",
      94                 :            :                                 target_uncore_freq, ui->pkg, ui->die);
      95                 :            : 
      96                 :            :         /* write the minimum value first if the target freq is less than current max */
      97         [ #  # ]:          0 :         if (target_uncore_freq <= curr_max_freq) {
      98                 :          0 :                 fflush(ui->f_cur_min);
      99                 :          0 :                 fflush(ui->f_cur_max);
     100                 :            :         } else {
     101                 :          0 :                 fflush(ui->f_cur_max);
     102                 :          0 :                 fflush(ui->f_cur_min);
     103                 :            :         }
     104                 :          0 :         ui->curr_idx = idx;
     105                 :            : 
     106                 :          0 :         return 0;
     107                 :            : }
     108                 :            : 
     109                 :            : /*
     110                 :            :  * Fopen the sys file for the future setting of the uncore die frequency.
     111                 :            :  */
     112                 :            : static int
     113                 :          0 : power_init_for_setting_uncore_freq(struct uncore_power_info *ui)
     114                 :            : {
     115                 :          0 :         FILE *f_base_min = NULL, *f_base_max = NULL, *f_min = NULL, *f_max = NULL;
     116                 :          0 :         uint32_t base_min_freq = 0, base_max_freq = 0, min_freq = 0, max_freq = 0;
     117                 :            :         int ret;
     118                 :            : 
     119                 :            :         /* open and read all uncore sys files */
     120                 :            :         /* Base max */
     121                 :          0 :         open_core_sysfs_file(&f_base_max, "r", POWER_INTEL_UNCORE_SYSFILE_BASE_MAX_FREQ,
     122                 :            :                         ui->pkg, ui->die);
     123         [ #  # ]:          0 :         if (f_base_max == NULL) {
     124                 :          0 :                 POWER_LOG(DEBUG, "failed to open %s",
     125                 :            :                                 POWER_INTEL_UNCORE_SYSFILE_BASE_MAX_FREQ);
     126                 :          0 :                 goto err;
     127                 :            :         }
     128                 :          0 :         ret = read_core_sysfs_u32(f_base_max, &base_max_freq);
     129         [ #  # ]:          0 :         if (ret < 0) {
     130                 :          0 :                 POWER_LOG(DEBUG, "Failed to read %s",
     131                 :            :                                 POWER_INTEL_UNCORE_SYSFILE_BASE_MAX_FREQ);
     132                 :          0 :                 goto err;
     133                 :            :         }
     134                 :            : 
     135                 :            :         /* Base min */
     136                 :          0 :         open_core_sysfs_file(&f_base_min, "r", POWER_INTEL_UNCORE_SYSFILE_BASE_MIN_FREQ,
     137                 :            :                 ui->pkg, ui->die);
     138         [ #  # ]:          0 :         if (f_base_min == NULL) {
     139                 :          0 :                 POWER_LOG(DEBUG, "failed to open %s",
     140                 :            :                                 POWER_INTEL_UNCORE_SYSFILE_BASE_MIN_FREQ);
     141                 :          0 :                 goto err;
     142                 :            :         }
     143                 :            :         if (f_base_min != NULL) {
     144                 :          0 :                 ret = read_core_sysfs_u32(f_base_min, &base_min_freq);
     145         [ #  # ]:          0 :                 if (ret < 0) {
     146                 :          0 :                         POWER_LOG(DEBUG, "Failed to read %s",
     147                 :            :                                         POWER_INTEL_UNCORE_SYSFILE_BASE_MIN_FREQ);
     148                 :          0 :                         goto err;
     149                 :            :                 }
     150                 :            :         }
     151                 :            : 
     152                 :            :         /* Curr min */
     153                 :          0 :         open_core_sysfs_file(&f_min, "rw+", POWER_INTEL_UNCORE_SYSFILE_MIN_FREQ,
     154                 :            :                         ui->pkg, ui->die);
     155         [ #  # ]:          0 :         if (f_min == NULL) {
     156                 :          0 :                 POWER_LOG(DEBUG, "failed to open %s",
     157                 :            :                                 POWER_INTEL_UNCORE_SYSFILE_MIN_FREQ);
     158                 :          0 :                 goto err;
     159                 :            :         }
     160                 :            :         if (f_min != NULL) {
     161                 :          0 :                 ret = read_core_sysfs_u32(f_min, &min_freq);
     162         [ #  # ]:          0 :                 if (ret < 0) {
     163                 :          0 :                         POWER_LOG(DEBUG, "Failed to read %s",
     164                 :            :                                         POWER_INTEL_UNCORE_SYSFILE_MIN_FREQ);
     165                 :          0 :                         goto err;
     166                 :            :                 }
     167                 :            :         }
     168                 :            : 
     169                 :            :         /* Curr max */
     170                 :          0 :         open_core_sysfs_file(&f_max, "rw+", POWER_INTEL_UNCORE_SYSFILE_MAX_FREQ,
     171                 :            :                         ui->pkg, ui->die);
     172         [ #  # ]:          0 :         if (f_max == NULL) {
     173                 :          0 :                 POWER_LOG(DEBUG, "failed to open %s",
     174                 :            :                                 POWER_INTEL_UNCORE_SYSFILE_MAX_FREQ);
     175                 :          0 :                 goto err;
     176                 :            :         }
     177                 :            :         if (f_max != NULL) {
     178                 :          0 :                 ret = read_core_sysfs_u32(f_max, &max_freq);
     179         [ #  # ]:          0 :                 if (ret < 0) {
     180                 :          0 :                         POWER_LOG(DEBUG, "Failed to read %s",
     181                 :            :                                         POWER_INTEL_UNCORE_SYSFILE_MAX_FREQ);
     182                 :          0 :                         goto err;
     183                 :            :                 }
     184                 :            :         }
     185                 :            : 
     186                 :            :         /* assign file handles */
     187                 :          0 :         ui->f_cur_min = f_min;
     188                 :          0 :         ui->f_cur_max = f_max;
     189                 :            :         /* save current min + max freq's so that they can be restored on exit */
     190                 :          0 :         ui->org_min_freq = min_freq;
     191                 :          0 :         ui->org_max_freq = max_freq;
     192                 :          0 :         ui->init_max_freq = base_max_freq;
     193                 :          0 :         ui->init_min_freq = base_min_freq;
     194                 :            : 
     195                 :          0 :         fclose(f_base_min);
     196                 :          0 :         fclose(f_base_max);
     197                 :            :         /* f_min and f_max are stored, no need to close */
     198                 :            : 
     199                 :          0 :         return 0;
     200                 :            : 
     201                 :          0 : err:
     202         [ #  # ]:          0 :         if (f_base_min != NULL)
     203                 :          0 :                 fclose(f_base_min);
     204         [ #  # ]:          0 :         if (f_base_max != NULL)
     205                 :          0 :                 fclose(f_base_max);
     206         [ #  # ]:          0 :         if (f_min != NULL)
     207                 :          0 :                 fclose(f_min);
     208         [ #  # ]:          0 :         if (f_max != NULL)
     209                 :          0 :                 fclose(f_max);
     210                 :            :         return -1;
     211                 :            : }
     212                 :            : 
     213                 :            : /*
     214                 :            :  * Get the available uncore frequencies of the specific die by reading the
     215                 :            :  * sys file.
     216                 :            :  */
     217                 :            : static int
     218                 :          0 : power_get_available_uncore_freqs(struct uncore_power_info *ui)
     219                 :            : {
     220                 :            :         int ret = -1;
     221                 :            :         uint32_t i, num_uncore_freqs = 0;
     222                 :            : 
     223                 :          0 :         num_uncore_freqs = (ui->init_max_freq - ui->init_min_freq) / BUS_FREQ + 1;
     224         [ #  # ]:          0 :         if (num_uncore_freqs >= MAX_UNCORE_FREQS) {
     225                 :          0 :                 POWER_LOG(ERR, "Too many available uncore frequencies: %d",
     226                 :            :                                 num_uncore_freqs);
     227                 :          0 :                 goto out;
     228                 :            :         }
     229                 :            : 
     230                 :            :         /* Generate the uncore freq bucket array. */
     231         [ #  # ]:          0 :         for (i = 0; i < num_uncore_freqs; i++)
     232                 :          0 :                 ui->freqs[i] = ui->init_max_freq - (i) * BUS_FREQ;
     233                 :            : 
     234                 :          0 :         ui->nb_freqs = num_uncore_freqs;
     235                 :            : 
     236                 :            :         ret = 0;
     237                 :            : 
     238                 :            :         POWER_DEBUG_LOG("%d frequency(s) of pkg %02u die %02u are available",
     239                 :            :                         num_uncore_freqs, ui->pkg, ui->die);
     240                 :            : 
     241                 :          0 : out:
     242                 :          0 :         return ret;
     243                 :            : }
     244                 :            : 
     245                 :            : static int
     246                 :          0 : check_pkg_die_values(unsigned int pkg, unsigned int die)
     247                 :            : {
     248                 :            :         unsigned int max_pkgs, max_dies;
     249                 :          0 :         max_pkgs = power_intel_uncore_get_num_pkgs();
     250         [ #  # ]:          0 :         if (max_pkgs == 0)
     251                 :            :                 return -1;
     252         [ #  # ]:          0 :         if (pkg >= max_pkgs) {
     253                 :          0 :                 POWER_LOG(DEBUG, "Package number %02u can not exceed %u",
     254                 :            :                                 pkg, max_pkgs);
     255                 :          0 :                 return -1;
     256                 :            :         }
     257                 :            : 
     258                 :          0 :         max_dies = power_intel_uncore_get_num_dies(pkg);
     259         [ #  # ]:          0 :         if (max_dies == 0)
     260                 :            :                 return -1;
     261         [ #  # ]:          0 :         if (die >= max_dies) {
     262                 :          0 :                 POWER_LOG(DEBUG, "Die number %02u can not exceed %u",
     263                 :            :                                 die, max_dies);
     264                 :          0 :                 return -1;
     265                 :            :         }
     266                 :            : 
     267                 :            :         return 0;
     268                 :            : }
     269                 :            : 
     270                 :            : int
     271                 :          0 : power_intel_uncore_init(unsigned int pkg, unsigned int die)
     272                 :            : {
     273                 :            :         struct uncore_power_info *ui;
     274                 :            : 
     275                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     276         [ #  # ]:          0 :         if (ret < 0)
     277                 :            :                 return -1;
     278                 :            : 
     279                 :          0 :         ui = &uncore_info[pkg][die];
     280                 :          0 :         ui->die = die;
     281                 :          0 :         ui->pkg = pkg;
     282                 :            : 
     283                 :            :         /* Init for setting uncore die frequency */
     284         [ #  # ]:          0 :         if (power_init_for_setting_uncore_freq(ui) < 0) {
     285                 :          0 :                 POWER_LOG(DEBUG, "Cannot init for setting uncore frequency for "
     286                 :            :                                 "pkg %02u die %02u", pkg, die);
     287                 :          0 :                 return -1;
     288                 :            :         }
     289                 :            : 
     290                 :            :         /* Get the available frequencies */
     291         [ #  # ]:          0 :         if (power_get_available_uncore_freqs(ui) < 0) {
     292                 :          0 :                 POWER_LOG(DEBUG, "Cannot get available uncore frequencies of "
     293                 :            :                                 "pkg %02u die %02u", pkg, die);
     294                 :          0 :                 return -1;
     295                 :            :         }
     296                 :            : 
     297                 :            :         return 0;
     298                 :            : }
     299                 :            : 
     300                 :            : int
     301                 :          0 : power_intel_uncore_exit(unsigned int pkg, unsigned int die)
     302                 :            : {
     303                 :            :         struct uncore_power_info *ui;
     304                 :            : 
     305                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     306         [ #  # ]:          0 :         if (ret < 0)
     307                 :            :                 return -1;
     308                 :            : 
     309                 :            :         ui = &uncore_info[pkg][die];
     310                 :            : 
     311         [ #  # ]:          0 :         if (fprintf(ui->f_cur_min, "%u", ui->org_min_freq) < 0) {
     312                 :          0 :                 POWER_LOG(ERR, "Fail to write original uncore frequency for "
     313                 :            :                                 "pkg %02u die %02u", ui->pkg, ui->die);
     314                 :          0 :                 return -1;
     315                 :            :         }
     316                 :            : 
     317         [ #  # ]:          0 :         if (fprintf(ui->f_cur_max, "%u", ui->org_max_freq) < 0) {
     318                 :          0 :                 POWER_LOG(ERR, "Fail to write original uncore frequency for "
     319                 :            :                                 "pkg %02u die %02u", ui->pkg, ui->die);
     320                 :          0 :                 return -1;
     321                 :            :         }
     322                 :            : 
     323                 :          0 :         fflush(ui->f_cur_min);
     324                 :          0 :         fflush(ui->f_cur_max);
     325                 :            : 
     326                 :            :         /* Close FD of setting freq */
     327                 :          0 :         fclose(ui->f_cur_min);
     328                 :          0 :         fclose(ui->f_cur_max);
     329                 :          0 :         ui->f_cur_min = NULL;
     330                 :          0 :         ui->f_cur_max = NULL;
     331                 :            : 
     332                 :          0 :         return 0;
     333                 :            : }
     334                 :            : 
     335                 :            : uint32_t
     336                 :          0 : power_get_intel_uncore_freq(unsigned int pkg, unsigned int die)
     337                 :            : {
     338                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     339         [ #  # ]:          0 :         if (ret < 0)
     340                 :            :                 return -1;
     341                 :            : 
     342                 :          0 :         return uncore_info[pkg][die].curr_idx;
     343                 :            : }
     344                 :            : 
     345                 :            : int
     346                 :          0 : power_set_intel_uncore_freq(unsigned int pkg, unsigned int die, uint32_t index)
     347                 :            : {
     348                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     349         [ #  # ]:          0 :         if (ret < 0)
     350                 :            :                 return -1;
     351                 :            : 
     352                 :          0 :         return set_uncore_freq_internal(&(uncore_info[pkg][die]), index);
     353                 :            : }
     354                 :            : 
     355                 :            : int
     356                 :          0 : power_intel_uncore_freq_max(unsigned int pkg, unsigned int die)
     357                 :            : {
     358                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     359         [ #  # ]:          0 :         if (ret < 0)
     360                 :            :                 return -1;
     361                 :            : 
     362                 :          0 :         return set_uncore_freq_internal(&(uncore_info[pkg][die]), 0);
     363                 :            : }
     364                 :            : 
     365                 :            : 
     366                 :            : int
     367                 :          0 : power_intel_uncore_freq_min(unsigned int pkg, unsigned int die)
     368                 :            : {
     369                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     370         [ #  # ]:          0 :         if (ret < 0)
     371                 :            :                 return -1;
     372                 :            : 
     373                 :            :         struct uncore_power_info *ui = &uncore_info[pkg][die];
     374                 :            : 
     375                 :          0 :         return set_uncore_freq_internal(&(uncore_info[pkg][die]), ui->nb_freqs - 1);
     376                 :            : }
     377                 :            : 
     378                 :            : int
     379                 :          0 : power_intel_uncore_freqs(unsigned int pkg, unsigned int die, uint32_t *freqs, uint32_t num)
     380                 :            : {
     381                 :            :         struct uncore_power_info *ui;
     382                 :            : 
     383                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     384         [ #  # ]:          0 :         if (ret < 0)
     385                 :            :                 return -1;
     386                 :            : 
     387         [ #  # ]:          0 :         if (freqs == NULL) {
     388                 :          0 :                 POWER_LOG(ERR, "NULL buffer supplied");
     389                 :          0 :                 return 0;
     390                 :            :         }
     391                 :            : 
     392                 :            :         ui = &uncore_info[pkg][die];
     393         [ #  # ]:          0 :         if (num < ui->nb_freqs) {
     394                 :          0 :                 POWER_LOG(ERR, "Buffer size is not enough");
     395                 :          0 :                 return 0;
     396                 :            :         }
     397         [ #  # ]:          0 :         rte_memcpy(freqs, ui->freqs, ui->nb_freqs * sizeof(uint32_t));
     398                 :            : 
     399                 :          0 :         return ui->nb_freqs;
     400                 :            : }
     401                 :            : 
     402                 :            : int
     403                 :          0 : power_intel_uncore_get_num_freqs(unsigned int pkg, unsigned int die)
     404                 :            : {
     405                 :          0 :         int ret = check_pkg_die_values(pkg, die);
     406         [ #  # ]:          0 :         if (ret < 0)
     407                 :            :                 return -1;
     408                 :            : 
     409                 :          0 :         return uncore_info[pkg][die].nb_freqs;
     410                 :            : }
     411                 :            : 
     412                 :            : unsigned int
     413                 :          1 : power_intel_uncore_get_num_pkgs(void)
     414                 :            : {
     415                 :            :         DIR *d;
     416                 :            :         struct dirent *dir;
     417                 :            :         unsigned int count = 0;
     418                 :            :         char filter[FILTER_LENGTH];
     419                 :            : 
     420                 :          1 :         d = opendir(INTEL_UNCORE_FREQUENCY_DIR);
     421         [ +  - ]:          1 :         if (d == NULL) {
     422                 :          1 :                 POWER_LOG(ERR,
     423                 :            :                 "Uncore frequency management not supported/enabled on this kernel. "
     424                 :            :                 "Please enable CONFIG_INTEL_UNCORE_FREQ_CONTROL if on Intel x86 with linux kernel"
     425                 :            :                 " >= 5.6");
     426                 :          1 :                 return 0;
     427                 :            :         }
     428                 :            : 
     429                 :            :         /* search by incrementing file name for max pkg file value */
     430         [ #  # ]:          0 :         while ((dir = readdir(d)) != NULL) {
     431                 :            :                 snprintf(filter, FILTER_LENGTH, PACKAGE_FILTER, count);
     432                 :            :                 /* make sure filter string is in file name (don't include hidden files) */
     433         [ #  # ]:          0 :                 if (fnmatch(filter, dir->d_name, 0) == 0)
     434                 :          0 :                         count++;
     435                 :            :         }
     436                 :            : 
     437                 :          0 :         closedir(d);
     438                 :            : 
     439                 :          0 :         return count;
     440                 :            : }
     441                 :            : 
     442                 :            : unsigned int
     443                 :          0 : power_intel_uncore_get_num_dies(unsigned int pkg)
     444                 :            : {
     445                 :            :         DIR *d;
     446                 :            :         struct dirent *dir;
     447                 :            :         unsigned int count = 0, max_pkgs;
     448                 :            :         char filter[FILTER_LENGTH];
     449                 :            : 
     450                 :          0 :         max_pkgs = power_intel_uncore_get_num_pkgs();
     451         [ #  # ]:          0 :         if (max_pkgs == 0)
     452                 :            :                 return 0;
     453         [ #  # ]:          0 :         if (pkg >= max_pkgs) {
     454                 :          0 :                 POWER_LOG(DEBUG, "Invalid package number");
     455                 :          0 :                 return 0;
     456                 :            :         }
     457                 :            : 
     458                 :          0 :         d = opendir(INTEL_UNCORE_FREQUENCY_DIR);
     459         [ #  # ]:          0 :         if (d == NULL) {
     460                 :          0 :                 POWER_LOG(ERR,
     461                 :            :                 "Uncore frequency management not supported/enabled on this kernel. "
     462                 :            :                 "Please enable CONFIG_INTEL_UNCORE_FREQ_CONTROL if on Intel x86 with linux kernel"
     463                 :            :                 " >= 5.6");
     464                 :          0 :                 return 0;
     465                 :            :         }
     466                 :            : 
     467                 :            :         /* search by incrementing file name for max die file value */
     468         [ #  # ]:          0 :         while ((dir = readdir(d)) != NULL) {
     469                 :            :                 snprintf(filter, FILTER_LENGTH, DIE_FILTER, pkg, count);
     470                 :            :                 /* make sure filter string is in file name (don't include hidden files) */
     471         [ #  # ]:          0 :                 if (fnmatch(filter, dir->d_name, 0) == 0)
     472                 :          0 :                         count++;
     473                 :            :         }
     474                 :            : 
     475                 :          0 :         closedir(d);
     476                 :            : 
     477                 :          0 :         return count;
     478                 :            : }

Generated by: LCOV version 1.14