File: capability.py

package info (click to toggle)
intel-cmt-cat 25.04-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,732 kB
  • sloc: ansic: 52,004; python: 11,324; makefile: 2,201; perl: 1,165; javascript: 37; sh: 23
file content (355 lines) | stat: -rwxr-xr-x 13,343 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
################################################################################
# BSD LICENSE
#
# Copyright(c) 2019-2023 Intel Corporation. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#   * Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
#   * Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in
#     the documentation and/or other materials provided with the
#     distribution.
#   * Neither the name of Intel Corporation nor the names of its
#     contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
################################################################################

"""
The module defines PqosCap which can be used to read PQoS capabilities.
"""

from __future__ import absolute_import, division, print_function
import ctypes

from pqos.common import pqos_handle_error
from pqos.pqos import Pqos
from pqos.native_struct import CPqosCap, CPqosCapability, CPqosMonitor


class PqosCapabilityMonitoring(object):
    "PQoS monitoring capability"
    # pylint: disable=too-few-public-methods

    def __init__(self):
        self.mem_size = 0    # byte size of the structure
        self.max_rmid = 0    # max RMID supported by socket
        self.l3_size = 0     # L3 cache size in bytes
        self.events = []     # a list of supported events


class PqosCapabilityL3Ca(object):
    "PQoS L3 cache allocation capability"
    # pylint: disable=too-few-public-methods,too-many-instance-attributes

    def __init__(self):
        self.mem_size = 0               # byte size of the structure
        self.num_classes = 0            # number of classes of service
        self.num_ways = 0               # number of cache ways
        self.way_size = 0               # way size in bytes
        self.way_contention = 0         # ways contention bit mask
        self.cdp = False                # code data prioritization feature support
        self.cdp_on = False             # code data prioritization on or off
        self.non_contiguous_cbm = False # Non-Contiguous CBM support


class PqosCapabilityL2Ca(object):
    "PQoS L2 cache allocation capability"
    # pylint: disable=too-few-public-methods,too-many-instance-attributes

    def __init__(self):
        self.mem_size = 0               # byte size of the structure
        self.num_classes = 0            # number of classes of service
        self.num_ways = 0               # number of cache ways
        self.way_size = 0               # way size in bytes
        self.way_contention = 0         # ways contention bit mask
        self.cdp = False                # code data prioritization feature support
        self.cdp_on = False             # code data prioritization on or off
        self.non_contiguous_cbm = False # Non-Contiguous CBM support


class PqosCapabilityMba(object):
    "PQoS memory bandwidth allocation capability"
    # pylint: disable=too-few-public-methods

    def __init__(self):
        self.mem_size = 0              # byte size of the structure
        self.num_classes = 0           # number of classes of service
        self.throttle_max = 0          # the max MBA can be throttled
        self.throttle_step = 0         # MBA granularity
        self.is_linear = False         # the type of MBA linear/nonlinear
        self.ctrl = False              # MBA controller support
        self.ctrl_on = False           # MBA controller on or off


def _get_tristate_bool(c_val):
    "Converts tri-state integer value -1, 0 or 1 to None, False or True."
    tristate_map = {
        1: True,
        0: False,
        -1: None
    }

    return tristate_map.get(c_val)


def _get_cap_mon(p_capability):
    """
    Converts low-level pqos_cap_mon structure to
    high-level PqosCapabilityMonitoring object.
    """
    c_capability = p_capability.contents
    capability = PqosCapabilityMonitoring()
    capability.mem_size = c_capability.mem_size
    capability.max_rmid = c_capability.max_rmid
    capability.l3_size = c_capability.l3_size

    events_ptr = ctypes.cast(c_capability.events, ctypes.POINTER(CPqosMonitor))

    for i in range(c_capability.num_events):
        capability.events.append(events_ptr[i])

    return capability


def _get_cap_l3ca(p_capability):
    """
    Converts low-level pqos_cap_l3ca structure to
    high-level PqosCapabilityL3Ca object.
    """
    c_capability = p_capability.contents
    capability = PqosCapabilityL3Ca()
    capability.mem_size = c_capability.mem_size
    capability.num_classes = c_capability.num_classes
    capability.num_ways = c_capability.num_ways
    capability.way_size = c_capability.way_size
    capability.way_contention = c_capability.way_contention
    capability.cdp = _get_tristate_bool(c_capability.cdp)
    capability.cdp_on = _get_tristate_bool(c_capability.cdp_on)
    capability.non_contiguous_cbm = c_capability.non_contiguous_cbm
    return capability


def _get_cap_l2ca(p_capability):
    """
    Converts low-level pqos_cap_l2ca structure to
    high-level PqosCapabilityL2Ca object.
    """
    c_capability = p_capability.contents
    capability = PqosCapabilityL2Ca()
    capability.mem_size = c_capability.mem_size
    capability.num_classes = c_capability.num_classes
    capability.num_ways = c_capability.num_ways
    capability.way_size = c_capability.way_size
    capability.way_contention = c_capability.way_contention
    capability.cdp = _get_tristate_bool(c_capability.cdp)
    capability.cdp_on = _get_tristate_bool(c_capability.cdp_on)
    capability.non_contiguous_cbm = c_capability.non_contiguous_cbm
    return capability


def _get_cap_mba(p_capability):
    """
    Converts low-level pqos_cap_mba structure to
    high-level PqosCapabilityMba object.
    """
    c_capability = p_capability.contents
    capability = PqosCapabilityMba()
    capability.mem_size = c_capability.mem_size
    capability.num_classes = c_capability.num_classes
    capability.throttle_max = c_capability.throttle_max
    capability.throttle_step = c_capability.throttle_step
    capability.is_linear = c_capability.is_linear == 1
    capability.ctrl = _get_tristate_bool(c_capability.ctrl)
    capability.ctrl_on = _get_tristate_bool(c_capability.ctrl_on)
    return capability


def pqos_get_type_enum(type_str):
    "Converts capability type string to pqos_capability's enum."
    type_enum_map = {
        'mon': CPqosCapability.PQOS_CAP_TYPE_MON,
        'l3ca': CPqosCapability.PQOS_CAP_TYPE_L3CA,
        'l2ca': CPqosCapability.PQOS_CAP_TYPE_L2CA,
        'mba': CPqosCapability.PQOS_CAP_TYPE_MBA
    }

    return type_enum_map[type_str.lower()]


def _get_capability(cap_item, type_str):
    "Converts capability type string to pqos_capability's enum."
    type_cls_map = {
        'mon': (_get_cap_mon, lambda c: c.u.mon),
        'l3ca': (_get_cap_l3ca, lambda c: c.u.l3ca),
        'l2ca': (_get_cap_l2ca, lambda c: c.u.l2ca),
        'mba': (_get_cap_mba, lambda c: c.u.mba)
    }
    capability_func, cap_item_func = type_cls_map[type_str.lower()]
    return capability_func(cap_item_func(cap_item))


class PqosCap(object):
    "PQoS capabilities"

    def __init__(self):
        "Initializes capabilities, calls pqos_cap_get."

        self.pqos = Pqos()
        self.p_cap = ctypes.POINTER(CPqosCap)()
        ret = self.pqos.lib.pqos_cap_get(ctypes.byref(self.p_cap), None)
        pqos_handle_error('pqos_cap_get', ret)

    def get_type(self, type_str):
        """
        Retrieves a type of capability from a cap structure.

        Parameters:
            type_str: a string indicating a type of capability, available
                      options: mon, l3ca, l2ca and mba

        Returns:
            capabilities
        """

        type_enum = pqos_get_type_enum(type_str)
        p_cap_item = ctypes.POINTER(CPqosCapability)()
        ret = self.pqos.lib.pqos_cap_get_type(self.p_cap, type_enum,
                                              ctypes.byref(p_cap_item))
        pqos_handle_error('pqos_cap_get_type', ret)

        cap_item = p_cap_item.contents
        capability = _get_capability(cap_item, type_str)
        return capability

    def get_l3ca_cos_num(self):
        """
        Retrieves number of L3 allocation classes of service from
        a cap structure.

        Returns:
            a number of L3 allocation classes
        """

        cos_num = ctypes.c_uint(0)
        ret = self.pqos.lib.pqos_l3ca_get_cos_num(self.p_cap,
                                                  ctypes.byref(cos_num))
        pqos_handle_error('pqos_l3ca_get_cos_num', ret)
        return cos_num.value

    def get_l2ca_cos_num(self):
        """
        Retrieves number of L2 allocation classes of service from
        a cap structure.

        Returns:
            a number of L2 allocation classes
        """

        cos_num = ctypes.c_uint(0)
        ret = self.pqos.lib.pqos_l2ca_get_cos_num(self.p_cap,
                                                  ctypes.byref(cos_num))
        pqos_handle_error('pqos_l2ca_get_cos_num', ret)
        return cos_num.value

    def get_mba_cos_num(self):
        """
        Retrieves number of memory B/W allocation classes of service from
        a cap structure.

        Returns:
            a number of memory B/W allocation classes
        """

        cos_num = ctypes.c_uint(0)
        ret = self.pqos.lib.pqos_mba_get_cos_num(self.p_cap,
                                                 ctypes.byref(cos_num))
        pqos_handle_error('pqos_mba_get_cos_num', ret)
        return cos_num.value

    def is_l3ca_cdp_enabled(self):
        """
        Retrieves L3 CDP status.

        Returns:
            a tuple of two values: supported (True, False or None)
              and enabled (True, False or None)
        """

        supported = ctypes.c_int(0)
        enabled = ctypes.c_int(0)
        ret = self.pqos.lib.pqos_l3ca_cdp_enabled(self.p_cap,
                                                  ctypes.byref(supported),
                                                  ctypes.byref(enabled))
        pqos_handle_error('pqos_l3ca_cdp_enabled', ret)
        return (_get_tristate_bool(supported.value),
                _get_tristate_bool(enabled.value))

    def is_l2ca_cdp_enabled(self):
        """
        Retrieves L2 CDP status.

        Returns:
            a tuple of two values: supported (True, False or None)
              and enabled (True, False or None)
        """

        supported = ctypes.c_int(0)
        enabled = ctypes.c_int(0)
        ret = self.pqos.lib.pqos_l2ca_cdp_enabled(self.p_cap,
                                                  ctypes.byref(supported),
                                                  ctypes.byref(enabled))
        pqos_handle_error('pqos_l2ca_cdp_enabled', ret)
        return (_get_tristate_bool(supported.value),
                _get_tristate_bool(enabled.value))

    def is_mba_ctrl_enabled(self):
        """
        Retrieves MBA CTRL status.

        Returns:
            a tuple of two values: supported (True, False or None)
              and enabled (True, False or None)
        """

        supported = ctypes.c_int(0)
        enabled = ctypes.c_int(0)
        ret = self.pqos.lib.pqos_mba_ctrl_enabled(self.p_cap,
                                                  ctypes.byref(supported),
                                                  ctypes.byref(enabled))
        pqos_handle_error('pqos_mba_ctrl_enabled', ret)
        return (_get_tristate_bool(supported.value),
                _get_tristate_bool(enabled.value))

    def is_l3ca_iordt_enabled(self):
        """
        Retrieves L3 cache allocation I/O RDT status.

        Returns:
            a tuple of two values: supported (True, False or None)
              and enabled (True, False or None)
        """

        supported = ctypes.c_int(0)
        enabled = ctypes.c_int(0)
        ret = self.pqos.lib.pqos_l3ca_iordt_enabled(self.p_cap,
                                                    ctypes.byref(supported),
                                                    ctypes.byref(enabled))
        pqos_handle_error('pqos_l3ca_iordt_enabled', ret)
        return (_get_tristate_bool(supported.value),
                _get_tristate_bool(enabled.value))