NVIDIA DOCA SDK Data Center on a Chip Framework Documentation
doca_transport_dev.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2024 NVIDIA CORPORATION AND AFFILIATES. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are permitted
5  * provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright notice, this list of
7  * conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright notice, this list of
9  * conditions and the following disclaimer in the documentation and/or other materials
10  * provided with the distribution.
11  * * Neither the name of the NVIDIA CORPORATION nor the names of its contributors may be used
12  * to endorse or promote products derived from this software without specific prior written
13  * permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
20  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
21  * STRICT LIABILITY, OR TOR (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25 
26 #include <doca_dpa_dev.h>
29 
30 #include <doca_transport_common.h>
31 
32 /*
33  * RPC for initializing DPA IO thread called before running the thread
34  *
35  * @db_comp [in]: The DB completion context
36  * @cq_db [in]: The CQ DB
37  * @consumer [in]: The DPA Comch consumer
38  * @return: returns RPC_RETURN_STATUS_SUCCESS on success and RPC_RETURN_STATUS_ERROR otherwise
39  */
43 {
45  if (ret != 0) {
47  "Failed to initialize IO DPA thread: Failed to bind CQ to CQ completion context - %d",
48  ret);
50  }
52 
54 }
55 
56 /*
57  * Method for handling a message received from DPU
58  *
59  * @thread_arg [in]: The thread argument
60  * @msg [in]: The received message
61  */
62 static void handle_dpu_msg(struct io_thread_arg *thread_arg, const struct comch_msg *msg)
63 {
64  doca_dpa_dev_comch_producer_t producer = thread_arg->dpa_producer;
66  struct comch_msg msg_reply;
68 
69  switch (msg->type) {
71  db = msg->bind_sq_db_data.db;
73 
74  msg_reply = (struct comch_msg){
76  .bind_sq_db_done_data =
77  {
78  .cookie = msg->bind_sq_db_data.cookie,
79  },
80  };
82  /*consumer_id=*/1,
83  (const uint8_t *)&msg_reply,
84  sizeof(msg_reply),
87  break;
89  db = msg->unbind_sq_db_data.db;
91 
92  msg_reply = (struct comch_msg){
94  .unbind_sq_db_done_data =
95  {
96  .cookie = msg->unbind_sq_db_data.cookie,
97  },
98  };
100  /*consumer_id=*/1,
101  (const uint8_t *)&msg_reply,
102  sizeof(msg_reply),
105  break;
108  break;
109  default:
110  break;
111  }
112 }
113 
114 /*
115  * Method for handling all messages received from DPU
116  *
117  * @thread_arg [in]: The thread argument
118  */
119 static void handle_dpu_msgs(struct io_thread_arg *thread_arg)
120 {
122  const struct comch_msg *msg;
123  uint32_t msg_size;
124  doca_dpa_dev_comch_consumer_t consumer = thread_arg->dpa_consumer;
126 
127  uint32_t num_msgs = 0;
128  while (doca_dpa_dev_comch_consumer_get_completion(consumer_comp, &completion) != 0) {
129  msg = (const struct comch_msg *)doca_dpa_dev_comch_consumer_get_completion_imm(completion, &msg_size);
130  handle_dpu_msg(thread_arg, msg);
131  num_msgs++;
132  }
133 
134  if (num_msgs != 0) {
135  doca_dpa_dev_comch_consumer_completion_ack(consumer_comp, num_msgs);
137  doca_dpa_dev_comch_consumer_ack(consumer, num_msgs);
138  }
139 }
140 
141 #define MAX_DBS 64
142 
146 };
147 
148 /*
149  * Method for handling a single CQ/SQ DB value received from Host
150  *
151  * @thread_arg [in]: The thread argument
152  * @db [in]: The properties of the received DB
153  */
154 static void handle_db(struct io_thread_arg *thread_arg, struct db_completion_properties *db)
155 {
158 
159  struct comch_msg msg = {
161  .host_db_data =
162  {
163  .db_user_data = db->user_data,
164  .db_value = db_value,
165  },
166  };
168  /*consumer_id=*/1,
169  (const uint8_t *)&msg,
170  sizeof(msg),
173 }
174 
175 /*
176  * Method for handling all CQ/SQ DBs received from Host
177  *
178  * @thread_arg [in]: The thread argument
179  */
180 static void handle_dbs(struct io_thread_arg *thread_arg)
181 {
182  struct db_completion_properties dbs[MAX_DBS];
183  uint32_t num_dbs;
184  uint32_t db_idx;
186 
187  num_dbs = 0;
190  db_comp,
191  &dbs[num_dbs].db,
192  &dbs[num_dbs].user_data);
193  num_dbs++;
194  }
195 
196  if (num_dbs != 0) {
199  }
200 
201  for (db_idx = 0; db_idx < num_dbs; db_idx++) {
202  handle_db(thread_arg, &dbs[db_idx]);
203  }
204 }
205 
206 /*
207  * The IO thread handler
208  *
209  * This handler is called whenever one of the following happens:
210  * - The consumer has received a message from the DPU
211  * - The Host has rung the NVMe CQ doorbell
212  * - The Host has rung the NVMe SQ doorbell of SQ
213  *
214  * @thread_arg_raw [in]: Represents pointer to thread argument initialized on the DPU
215  */
216 __dpa_global__ void io_thread(uint64_t thread_arg_raw)
217 {
218  struct io_thread_arg *thread_arg = (struct io_thread_arg *)thread_arg_raw;
219 
220  handle_dpu_msgs(thread_arg);
221  handle_dbs(thread_arg);
223 }
doca_dpa_dev_devemu_pci_db_completion_t db_comp
uint64_t db
#define RPC_RETURN_STATUS_ERROR
#define MAX_NUM_COMCH_MSGS
uint32_t db_value
#define RPC_RETURN_STATUS_SUCCESS
@ COMCH_MSG_TYPE_RAISE_MSIX
@ COMCH_MSG_TYPE_BIND_SQ_DB_DONE
@ COMCH_MSG_TYPE_HOST_DB
@ COMCH_MSG_TYPE_UNBIND_SQ_DB_DONE
@ COMCH_MSG_TYPE_UNBIND_SQ_DB
@ COMCH_MSG_TYPE_BIND_SQ_DB
#define MAX_DBS
static void handle_db(struct io_thread_arg *thread_arg, struct db_completion_properties *db)
static void handle_dpu_msg(struct io_thread_arg *thread_arg, const struct comch_msg *msg)
static void handle_dpu_msgs(struct io_thread_arg *thread_arg)
static void handle_dbs(struct io_thread_arg *thread_arg)
__dpa_global__ void io_thread(uint64_t thread_arg_raw)
__dpa_rpc__ uint64_t io_thread_init_rpc(doca_dpa_dev_devemu_pci_db_completion_t db_comp, doca_dpa_dev_devemu_pci_db_t cq_db, doca_dpa_dev_comch_consumer_t consumer)
struct dpa_thread_arg __dpa_global__
uint64_t doca_dpa_dev_comch_consumer_completion_t
DPA handle for DPA consumer completion context.
uint64_t doca_dpa_dev_comch_consumer_t
DPA handle for DPA consumer.
uint64_t doca_dpa_dev_comch_producer_t
DPA handle for DPA producer.
uint64_t doca_dpa_dev_devemu_pci_db_completion_t
DPA handle for emulated PCI device doorbell completion context.
uint64_t doca_dpa_dev_devemu_pci_db_t
DPA handle for emulated PCI device doorbell.
DOCA_EXPERIMENTAL void doca_dpa_dev_comch_consumer_completion_request_notification(doca_dpa_dev_comch_consumer_completion_t consumer_comp_handle)
Request notification on the Comch consumer completion context.
DOCA_EXPERIMENTAL void doca_dpa_dev_comch_consumer_completion_ack(doca_dpa_dev_comch_consumer_completion_t consumer_comp_handle, uint64_t num_comp)
Acknowledge that the completions have been read on the Comch consumer completion context.
DOCA_EXPERIMENTAL const uint8_t * doca_dpa_dev_comch_consumer_get_completion_imm(doca_dpa_dev_comch_consumer_completion_element_t comp_element, uint32_t *imm_length)
Get Comch consumer completion immediate data.
__dpa_global__ typedef uint64_t doca_dpa_dev_comch_consumer_completion_element_t
DPA Comch consumer completion element handle type definition.
DOCA_EXPERIMENTAL void doca_dpa_dev_comch_consumer_ack(doca_dpa_dev_comch_consumer_t consumer, uint32_t num_msg)
Post multiple receive operations that receive immediate data only.
DOCA_EXPERIMENTAL int doca_dpa_dev_comch_consumer_get_completion(doca_dpa_dev_comch_consumer_completion_t consumer_comp_handle, doca_dpa_dev_comch_consumer_completion_element_t *comp_element)
Get Comch consumer completion element.
DOCA_EXPERIMENTAL void doca_dpa_dev_comch_producer_post_send_imm_only(doca_dpa_dev_comch_producer_t producer, uint32_t consumer_id, const uint8_t *imm, uint32_t imm_length, uint32_t flags)
Post a producer send immediate data only operation.
__dpa_global__ typedef uint64_t doca_dpa_dev_devemu_pci_db_completion_element_t
DPA Devemu PCI Device DB Completion Element handle type definition.
DOCA_EXPERIMENTAL void doca_dpa_dev_devemu_pci_db_completion_request_notification(doca_dpa_dev_devemu_pci_db_completion_t comp)
Request notification on the Devemu PCI Device DB completion context.
DOCA_EXPERIMENTAL uint32_t doca_dpa_dev_devemu_pci_db_get_value(doca_dpa_dev_devemu_pci_db_t db)
Get value written to the doorbell.
DOCA_EXPERIMENTAL int doca_dpa_dev_devemu_pci_db_completion_bind_db(doca_dpa_dev_devemu_pci_db_completion_t comp, doca_dpa_dev_devemu_pci_db_t db)
Bind Devemu PCI Device DB handle to the Devemu PCI Device DB completion context.
DOCA_EXPERIMENTAL void doca_dpa_dev_devemu_pci_db_completion_ack(doca_dpa_dev_devemu_pci_db_completion_t comp, uint64_t num_comp)
Acknowledge that the completions have been read on the Devemu PCI Device DB completion context.
DOCA_EXPERIMENTAL void doca_dpa_dev_devemu_pci_db_completion_element_get_db_properties(doca_dpa_dev_devemu_pci_db_completion_t comp, doca_dpa_dev_devemu_pci_db_completion_element_t comp_element, doca_dpa_dev_devemu_pci_db_t *db, doca_dpa_dev_uintptr_t *db_user_data)
Get Devemu PCI Device DB properties from DB completion element.
DOCA_EXPERIMENTAL void doca_dpa_dev_devemu_pci_db_request_notification(doca_dpa_dev_devemu_pci_db_t db)
Request notification on the Devemu PCI Device DB context.
DOCA_EXPERIMENTAL int doca_dpa_dev_devemu_pci_db_completion_unbind_db(doca_dpa_dev_devemu_pci_db_completion_t comp, doca_dpa_dev_devemu_pci_db_t db)
Unbind Devemu PCI Device DB handle from the Devemu PCI Device DB completion context.
DOCA_EXPERIMENTAL void doca_dpa_dev_devemu_pci_msix_raise(doca_dpa_dev_devemu_pci_msix_t msix)
Raise MSIX notification towards the driver.
DOCA_EXPERIMENTAL int doca_dpa_dev_devemu_pci_get_db_completion(doca_dpa_dev_devemu_pci_db_completion_t comp, doca_dpa_dev_devemu_pci_db_completion_element_t *comp_element)
Get Devemu PCI Device DB completion element.
DOCA_EXPERIMENTAL void doca_dpa_dev_thread_reschedule(void)
Reschedule a DPA thread.
#define DOCA_DPA_DEV_LOG_ERR(...)
Generate a DOCA DPA device ERROR log message.
Definition: doca_dpa_dev.h:271
@ DOCA_DPA_DEV_SUBMIT_FLAG_OPTIMIZE_REPORTS
Definition: doca_dpa_dev.h:113
@ DOCA_DPA_DEV_SUBMIT_FLAG_FLUSH
Definition: doca_dpa_dev.h:106
uint64_t doca_dpa_dev_uintptr_t
DPA pointer type definition.
Definition: doca_dpa.h:78
struct comch_msg::@18::@19 bind_sq_db_data
enum comch_msg_type type
Definition: dma_copy_core.h:73
struct comch_msg::@18::@21 unbind_sq_db_data
doca_dpa_dev_uintptr_t user_data
doca_dpa_dev_devemu_pci_db_t db