File: flow.pyx

package info (click to toggle)
rdma-core 56.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 17,196 kB
  • sloc: ansic: 171,361; python: 13,724; sh: 2,774; perl: 1,465; makefile: 73
file content (134 lines) | stat: -rw-r--r-- 4,178 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
# SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB)
# Copyright (c) 2020 Nvidia All rights reserved.

from pyverbs.pyverbs_error import PyverbsRDMAError, PyverbsError
from pyverbs.base import PyverbsRDMAErrno
from libc.stdlib cimport calloc, free
from libc.string cimport memcpy
from pyverbs.qp cimport QP


cdef class FlowAttr(PyverbsObject):
    def __init__(self, num_of_specs=0, flow_type=v.IBV_FLOW_ATTR_NORMAL,
                 priority=0, port=1, flags=0):
        """
        Initialize a FlowAttr object over an underlying ibv_flow_attr C object
        which contains attributes for creating a steering flow.
        :param num_of_specs: number of specs
        :param flow_type: flow type
        :param priority: flow priority
        :param port: port number
        :param flags: flow flags
        """
        super().__init__()
        self.attr.type = flow_type
        self.attr.size = sizeof(v.ibv_flow_attr)
        self.attr.priority = priority
        self.attr.num_of_specs = num_of_specs
        self.attr.port = port
        self.attr.flags = flags
        self.specs = list()

    @property
    def type(self):
        return self.attr.type

    @type.setter
    def type(self, val):
        self.attr.type = val

    @property
    def priority(self):
        return self.attr.priority

    @priority.setter
    def priority(self, val):
        self.attr.priority = val

    @property
    def num_of_specs(self):
        return self.attr.num_of_specs

    @num_of_specs.setter
    def num_of_specs(self, val):
        self.attr.num_of_specs = val

    @property
    def port(self):
        return self.attr.port

    @port.setter
    def port(self, val):
        self.attr.port = val

    @property
    def flags(self):
        return self.attr.flags

    @flags.setter
    def flags(self, val):
        self.attr.flags = val

    @property
    def specs(self):
        return self.specs


cdef class Flow(PyverbsCM):
    def __init__(self, QP qp, FlowAttr flow_attr):
        """
        Initialize a Flow object over an underlying ibv_flow C object which
        represents a steering flow.
        :param qp: QP to create flow for
        :param flow_attr: Flow attributes for flow creation
        """
        super().__init__()
        cdef char *flow_addr
        cdef char *dst_addr
        cdef v.ibv_flow_attr attr = flow_attr.attr
        if flow_attr.num_of_specs != len(flow_attr.specs):
            self.logger.warn(f'The number of appended specs '
                             f'({len(flow_attr.specs)}) is not equal to the '
                             f'number of declared specs '
                             f'({flow_attr.flow_attr.num_of_specs})')
        # Calculate total size for allocation
        total_size = sizeof(v.ibv_flow_attr)
        for spec in flow_attr.specs:
            total_size += spec.size
        flow_addr = <char*>calloc(1, total_size)
        if flow_addr == NULL:
            raise PyverbsError(f'Failed to allocate memory of size '
                               f'{total_size}')
        dst_addr = flow_addr
        # Copy flow_attr at the beginning of the allocated memory
        memcpy(dst_addr, &attr, sizeof(v.ibv_flow_attr))
        dst_addr = <char*>(dst_addr + sizeof(v.ibv_flow_attr))
        # Copy specs one after another into the allocated memory after flow_attr
        for spec in flow_attr.specs:
            spec._copy_data(<unsigned long>dst_addr)
            dst_addr += spec.size

        self.flow = v.ibv_create_flow(qp.qp, <v.ibv_flow_attr*>flow_addr)
        free(flow_addr)
        if self.flow == NULL:
            raise PyverbsRDMAErrno('Flow creation failed')
        self.qp = qp
        qp.add_ref(self)

    def __dealloc__(self):
        self.close()

    cpdef close(self):
        if self.flow != NULL:
            if self.logger:
                self.logger.debug('Closing Flow')
            rc = v.ibv_destroy_flow(self.flow)
            if rc != 0:
                raise PyverbsRDMAError('Failed to destroy Flow', rc)
            self.flow = NULL
            self.qp = None


cdef class FlowAction(PyverbsObject):
    def __cinit__(self):
        self.action = NULL