Commit aed37fb9 authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

sma: add bdev QoS helper functions



These helper functions can be used by any device manager that wants to
provide volume-level QoS support using bdev-based QoS mechanism.  A
device manager is responsible for making sure that a volume exists and
is attached to a given device, but the validity of the QoS parameters is
checked within the helper functions.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: I4d0efcf190a64b289b4cfbdf872f77e40a013d1f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/14268


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarKarol Latecki <karol.latecki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 784815ea
Loading
Loading
Loading
Loading

python/spdk/sma/qos.py

0 → 100644
+59 −0
Original line number Diff line number Diff line
import grpc

from spdk.rpc.client import JSONRPCException
from .common import format_volume_id
from .proto import sma_pb2


LIMIT_UNDEFINED = (1 << 64) - 1


class QosException(Exception):
    def __init__(self, code, message):
        self.code = code
        self.message = message


def set_volume_bdev_qos(client, params):
    class BdevLimit:
        def __init__(self, name, transform=lambda v: v):
            self.name = name
            self._transform = transform

        def get_value(self, value):
            return self._transform(value)

    supported_limits = {
            'rw_iops': BdevLimit('rw_ios_per_sec', lambda v: v * 1000),
            'rd_bandwidth': BdevLimit('r_mbytes_per_sec'),
            'wr_bandwidth': BdevLimit('w_mbytes_per_sec'),
            'rw_bandwidth': BdevLimit('rw_mbytes_per_sec')
    }
    # Check that none of the unsupported fields aren't set either
    if params.HasField('maximum'):
        for field, value in params.maximum.ListFields():
            if field.name in supported_limits.keys():
                continue
            if value != 0 and value != LIMIT_UNDEFINED:
                raise QosException(grpc.StatusCode.INVALID_ARGUMENT,
                                   f'Unsupported QoS limit: maximum.{field.name}')
    try:
        rpc_params = {'name': format_volume_id(params.volume_id)}
        for name, limit in supported_limits.items():
            value = getattr(params.maximum, name)
            if value != LIMIT_UNDEFINED:
                rpc_params[limit.name] = limit.get_value(value)
        client.call('bdev_set_qos_limit', rpc_params)
    except JSONRPCException:
        raise QosException(grpc.StatusCode.INTERNAL, 'Failed to set QoS')


def get_bdev_qos_capabilities():
    return sma_pb2.GetQosCapabilitiesResponse(
            max_volume_caps=sma_pb2.GetQosCapabilitiesResponse.QosCapabilities(
                rw_iops=True,
                rw_bandwidth=True,
                rd_bandwidth=True,
                wr_bandwidth=True
                ),
            )