forked from linux-rdma/rdma-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
flow.pyx
133 lines (112 loc) · 4.05 KB
/
flow.pyx
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
# 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:
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