LCOV - code coverage report
Current view: top level - spdk/lib/vhost - vhost_internal.h (source / functions) Hit Total Coverage
Test: Combined Lines: 6 6 100.0 %
Date: 2024-07-13 21:41:39 Functions: 2 2 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 4 8 50.0 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2017 Intel Corporation.
       3                 :            :  *   All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #ifndef SPDK_VHOST_INTERNAL_H
       7                 :            : #define SPDK_VHOST_INTERNAL_H
       8                 :            : #include <linux/virtio_config.h>
       9                 :            : 
      10                 :            : #include "spdk/stdinc.h"
      11                 :            : 
      12                 :            : #include <rte_vhost.h>
      13                 :            : 
      14                 :            : #include "spdk_internal/vhost_user.h"
      15                 :            : #include "spdk/bdev.h"
      16                 :            : #include "spdk/log.h"
      17                 :            : #include "spdk/util.h"
      18                 :            : #include "spdk/rpc.h"
      19                 :            : #include "spdk/config.h"
      20                 :            : 
      21                 :            : #define SPDK_VHOST_MAX_VQUEUES  256
      22                 :            : #define SPDK_VHOST_MAX_VQ_SIZE  1024
      23                 :            : 
      24                 :            : #define SPDK_VHOST_SCSI_CTRLR_MAX_DEVS 8
      25                 :            : 
      26                 :            : #define SPDK_VHOST_IOVS_MAX 129
      27                 :            : 
      28                 :            : #define SPDK_VHOST_VQ_MAX_SUBMISSIONS   32
      29                 :            : 
      30                 :            : /*
      31                 :            :  * Rate at which stats are checked for interrupt coalescing.
      32                 :            :  */
      33                 :            : #define SPDK_VHOST_STATS_CHECK_INTERVAL_MS 10
      34                 :            : /*
      35                 :            :  * Default threshold at which interrupts start to be coalesced.
      36                 :            :  */
      37                 :            : #define SPDK_VHOST_VQ_IOPS_COALESCING_THRESHOLD 60000
      38                 :            : 
      39                 :            : /*
      40                 :            :  * Timeout in seconds for vhost-user session stop message.
      41                 :            :  */
      42                 :            : #define SPDK_VHOST_SESSION_STOP_TIMEOUT_IN_SEC 3
      43                 :            : /*
      44                 :            :  * Stop retry timeout in seconds, this value should be greater than SPDK_VHOST_SESSION_STOP_TIMEOUT_IN_SEC.
      45                 :            :  */
      46                 :            : #define SPDK_VHOST_SESSION_STOP_RETRY_TIMEOUT_IN_SEC (SPDK_VHOST_SESSION_STOP_TIMEOUT_IN_SEC + 1)
      47                 :            : /*
      48                 :            :  * Stop retry period in microseconds
      49                 :            :  */
      50                 :            : #define SPDK_VHOST_SESSION_STOP_RETRY_PERIOD_IN_US 1000
      51                 :            : 
      52                 :            : /*
      53                 :            :  * Currently coalescing is not used by default.
      54                 :            :  * Setting this to value > 0 here or by RPC will enable coalescing.
      55                 :            :  */
      56                 :            : #define SPDK_VHOST_COALESCING_DELAY_BASE_US 0
      57                 :            : 
      58                 :            : #define SPDK_VHOST_FEATURES ((1ULL << VHOST_F_LOG_ALL) | \
      59                 :            :         (1ULL << VHOST_USER_F_PROTOCOL_FEATURES) | \
      60                 :            :         (1ULL << VIRTIO_F_VERSION_1) | \
      61                 :            :         (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | \
      62                 :            :         (1ULL << VIRTIO_RING_F_EVENT_IDX) | \
      63                 :            :         (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | \
      64                 :            :         (1ULL << VIRTIO_F_ANY_LAYOUT))
      65                 :            : 
      66                 :            : #define SPDK_VHOST_DISABLED_FEATURES ((1ULL << VIRTIO_RING_F_EVENT_IDX) | \
      67                 :            :         (1ULL << VIRTIO_F_NOTIFY_ON_EMPTY))
      68                 :            : 
      69                 :            : #define VRING_DESC_F_AVAIL      (1ULL << VRING_PACKED_DESC_F_AVAIL)
      70                 :            : #define VRING_DESC_F_USED       (1ULL << VRING_PACKED_DESC_F_USED)
      71                 :            : #define VRING_DESC_F_AVAIL_USED (VRING_DESC_F_AVAIL | VRING_DESC_F_USED)
      72                 :            : 
      73                 :            : typedef struct rte_vhost_resubmit_desc spdk_vhost_resubmit_desc;
      74                 :            : typedef struct rte_vhost_resubmit_info spdk_vhost_resubmit_info;
      75                 :            : typedef struct rte_vhost_inflight_desc_packed   spdk_vhost_inflight_desc;
      76                 :            : 
      77                 :            : struct spdk_vhost_virtqueue {
      78                 :            :         struct rte_vhost_vring vring;
      79                 :            :         struct rte_vhost_ring_inflight vring_inflight;
      80                 :            :         uint16_t last_avail_idx;
      81                 :            :         uint16_t last_used_idx;
      82                 :            : 
      83                 :            :         struct {
      84                 :            :                 /* To mark a descriptor as available in packed ring
      85                 :            :                  * Equal to avail_wrap_counter in spec.
      86                 :            :                  */
      87                 :            :                 uint8_t avail_phase     : 1;
      88                 :            :                 /* To mark a descriptor as used in packed ring
      89                 :            :                  * Equal to used_wrap_counter in spec.
      90                 :            :                  */
      91                 :            :                 uint8_t used_phase      : 1;
      92                 :            :                 uint8_t padding         : 5;
      93                 :            :                 bool packed_ring        : 1;
      94                 :            :         } packed;
      95                 :            : 
      96                 :            :         void *tasks;
      97                 :            : 
      98                 :            :         /* Request count from last stats check */
      99                 :            :         uint32_t req_cnt;
     100                 :            : 
     101                 :            :         /* Request count from last event */
     102                 :            :         uint16_t used_req_cnt;
     103                 :            : 
     104                 :            :         /* How long interrupt is delayed */
     105                 :            :         uint32_t irq_delay_time;
     106                 :            : 
     107                 :            :         /* Next time when we need to send event */
     108                 :            :         uint64_t next_event_time;
     109                 :            : 
     110                 :            :         /* Associated vhost_virtqueue in the virtio device's virtqueue list */
     111                 :            :         uint32_t vring_idx;
     112                 :            : 
     113                 :            :         struct spdk_vhost_session *vsession;
     114                 :            :         /* Polling group private thread context */
     115                 :            :         void *poll_group;
     116                 :            : 
     117                 :            :         struct spdk_interrupt *intr;
     118                 :            : } __attribute((aligned(SPDK_CACHE_LINE_SIZE)));
     119                 :            : 
     120                 :            : struct spdk_vhost_session {
     121                 :            :         struct spdk_vhost_dev *vdev;
     122                 :            : 
     123                 :            :         /* rte_vhost connection ID. */
     124                 :            :         int vid;
     125                 :            : 
     126                 :            :         /* Unique session ID. */
     127                 :            :         uint64_t id;
     128                 :            :         /* Unique session name. */
     129                 :            :         char *name;
     130                 :            : 
     131                 :            :         bool started;
     132                 :            :         bool starting;
     133                 :            :         bool needs_restart;
     134                 :            : 
     135                 :            :         struct rte_vhost_memory *mem;
     136                 :            : 
     137                 :            :         int task_cnt;
     138                 :            : 
     139                 :            :         uint16_t max_queues;
     140                 :            :         /* Maximum number of queues before restart, used with 'needs_restart' flag */
     141                 :            :         uint16_t original_max_queues;
     142                 :            : 
     143                 :            :         uint64_t negotiated_features;
     144                 :            : 
     145                 :            :         /* Local copy of device coalescing settings. */
     146                 :            :         uint32_t coalescing_delay_time_base;
     147                 :            :         uint32_t coalescing_io_rate_threshold;
     148                 :            : 
     149                 :            :         /* Next time when stats for event coalescing will be checked. */
     150                 :            :         uint64_t next_stats_check_time;
     151                 :            : 
     152                 :            :         /* Interval used for event coalescing checking. */
     153                 :            :         uint64_t stats_check_interval;
     154                 :            : 
     155                 :            :         /* Session's stop poller will only try limited times to destroy the session. */
     156                 :            :         uint32_t stop_retry_count;
     157                 :            : 
     158                 :            :         /**
     159                 :            :          * DPDK calls our callbacks synchronously but the work those callbacks
     160                 :            :          * perform needs to be async. Luckily, all DPDK callbacks are called on
     161                 :            :          * a DPDK-internal pthread and only related to the current session, so we'll
     162                 :            :          * just wait on a semaphore of this session in there.
     163                 :            :          */
     164                 :            :         sem_t dpdk_sem;
     165                 :            : 
     166                 :            :         /** Return code for the current DPDK callback */
     167                 :            :         int dpdk_response;
     168                 :            : 
     169                 :            :         struct spdk_vhost_virtqueue virtqueue[SPDK_VHOST_MAX_VQUEUES];
     170                 :            : 
     171                 :            :         TAILQ_ENTRY(spdk_vhost_session) tailq;
     172                 :            : };
     173                 :            : 
     174                 :            : struct spdk_vhost_user_dev {
     175                 :            :         struct spdk_vhost_dev *vdev;
     176                 :            : 
     177                 :            :         const struct spdk_vhost_user_dev_backend *user_backend;
     178                 :            : 
     179                 :            :         /* Saved original values used to setup coalescing to avoid integer
     180                 :            :          * rounding issues during save/load config.
     181                 :            :          */
     182                 :            :         uint32_t coalescing_delay_us;
     183                 :            :         uint32_t coalescing_iops_threshold;
     184                 :            : 
     185                 :            :         bool registered;
     186                 :            : 
     187                 :            :         /* Use this lock to protect multiple sessions. */
     188                 :            :         pthread_mutex_t lock;
     189                 :            : 
     190                 :            :         /* Current connections to the device */
     191                 :            :         TAILQ_HEAD(, spdk_vhost_session) vsessions;
     192                 :            : 
     193                 :            :         /* Increment-only session counter */
     194                 :            :         uint64_t vsessions_num;
     195                 :            : 
     196                 :            :         /* Number of pending asynchronous operations */
     197                 :            :         uint32_t pending_async_op_num;
     198                 :            : };
     199                 :            : 
     200                 :            : struct spdk_vhost_dev {
     201                 :            :         char *name;
     202                 :            :         char *path;
     203                 :            : 
     204                 :            :         bool use_default_cpumask;
     205                 :            :         struct spdk_thread *thread;
     206                 :            : 
     207                 :            :         uint64_t virtio_features;
     208                 :            :         uint64_t disabled_features;
     209                 :            :         uint64_t protocol_features;
     210                 :            : 
     211                 :            :         const struct spdk_vhost_dev_backend *backend;
     212                 :            : 
     213                 :            :         /* Context passed from transport */
     214                 :            :         void *ctxt;
     215                 :            : 
     216                 :            :         TAILQ_ENTRY(spdk_vhost_dev) tailq;
     217                 :            : };
     218                 :            : 
     219                 :            : static inline struct spdk_vhost_user_dev *
     220                 :      28780 : to_user_dev(struct spdk_vhost_dev *vdev)
     221                 :            : {
     222         [ -  + ]:      28780 :         assert(vdev != NULL);
     223                 :      28780 :         return vdev->ctxt;
     224                 :            : }
     225                 :            : 
     226                 :            : /**
     227                 :            :  * \param vdev vhost device.
     228                 :            :  * \param vsession vhost session.
     229                 :            :  * \param arg user-provided parameter.
     230                 :            :  *
     231                 :            :  * \return negative values will break the foreach call, meaning
     232                 :            :  * the function won't be called again. Return codes zero and
     233                 :            :  * positive don't have any effect.
     234                 :            :  */
     235                 :            : typedef int (*spdk_vhost_session_fn)(struct spdk_vhost_dev *vdev,
     236                 :            :                                      struct spdk_vhost_session *vsession,
     237                 :            :                                      void *arg);
     238                 :            : 
     239                 :            : /**
     240                 :            :  * \param vdev vhost device.
     241                 :            :  * \param arg user-provided parameter.
     242                 :            :  */
     243                 :            : typedef void (*spdk_vhost_dev_fn)(struct spdk_vhost_dev *vdev, void *arg);
     244                 :            : 
     245                 :            : struct spdk_vhost_user_dev_backend {
     246                 :            :         /**
     247                 :            :          * Size of additional per-session context data
     248                 :            :          * allocated whenever a new client connects.
     249                 :            :          */
     250                 :            :         size_t session_ctx_size;
     251                 :            : 
     252                 :            :         spdk_vhost_session_fn start_session;
     253                 :            :         spdk_vhost_session_fn stop_session;
     254                 :            :         int (*alloc_vq_tasks)(struct spdk_vhost_session *vsession, uint16_t qid);
     255                 :            :         int (*enable_vq)(struct spdk_vhost_session *vsession, struct spdk_vhost_virtqueue *vq);
     256                 :            : };
     257                 :            : 
     258                 :            : enum vhost_backend_type {
     259                 :            :         VHOST_BACKEND_BLK = 0,
     260                 :            :         VHOST_BACKEND_SCSI,
     261                 :            : };
     262                 :            : 
     263                 :            : struct spdk_vhost_dev_backend {
     264                 :            :         enum vhost_backend_type type;
     265                 :            : 
     266                 :            :         int (*vhost_get_config)(struct spdk_vhost_dev *vdev, uint8_t *config, uint32_t len);
     267                 :            :         int (*vhost_set_config)(struct spdk_vhost_dev *vdev, uint8_t *config,
     268                 :            :                                 uint32_t offset, uint32_t size, uint32_t flags);
     269                 :            : 
     270                 :            :         void (*dump_info_json)(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w);
     271                 :            :         void (*write_config_json)(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w);
     272                 :            :         int (*remove_device)(struct spdk_vhost_dev *vdev);
     273                 :            :         int (*set_coalescing)(struct spdk_vhost_dev *vdev, uint32_t delay_base_us,
     274                 :            :                               uint32_t iops_threshold);
     275                 :            :         void (*get_coalescing)(struct spdk_vhost_dev *vdev, uint32_t *delay_base_us,
     276                 :            :                                uint32_t *iops_threshold);
     277                 :            : };
     278                 :            : 
     279                 :            : void *vhost_gpa_to_vva(struct spdk_vhost_session *vsession, uint64_t addr, uint64_t len);
     280                 :            : 
     281                 :            : uint16_t vhost_vq_avail_ring_get(struct spdk_vhost_virtqueue *vq, uint16_t *reqs,
     282                 :            :                                  uint16_t reqs_len);
     283                 :            : 
     284                 :            : /**
     285                 :            :  * Get a virtio split descriptor at given index in given virtqueue.
     286                 :            :  * The descriptor will provide access to the entire descriptor
     287                 :            :  * chain. The subsequent descriptors are accessible via
     288                 :            :  * \c spdk_vhost_vring_desc_get_next.
     289                 :            :  * \param vsession vhost session
     290                 :            :  * \param vq virtqueue
     291                 :            :  * \param req_idx descriptor index
     292                 :            :  * \param desc pointer to be set to the descriptor
     293                 :            :  * \param desc_table descriptor table to be used with
     294                 :            :  * \c spdk_vhost_vring_desc_get_next. This might be either
     295                 :            :  * default virtqueue descriptor table or per-chain indirect
     296                 :            :  * table.
     297                 :            :  * \param desc_table_size size of the *desc_table*
     298                 :            :  * \return 0 on success, -1 if given index is invalid.
     299                 :            :  * If -1 is returned, the content of params is undefined.
     300                 :            :  */
     301                 :            : int vhost_vq_get_desc(struct spdk_vhost_session *vsession, struct spdk_vhost_virtqueue *vq,
     302                 :            :                       uint16_t req_idx, struct vring_desc **desc, struct vring_desc **desc_table,
     303                 :            :                       uint32_t *desc_table_size);
     304                 :            : 
     305                 :            : /**
     306                 :            :  * Get a virtio packed descriptor at given index in given virtqueue.
     307                 :            :  * The descriptor will provide access to the entire descriptor
     308                 :            :  * chain. The subsequent descriptors are accessible via
     309                 :            :  * \c vhost_vring_packed_desc_get_next.
     310                 :            :  * \param vsession vhost session
     311                 :            :  * \param vq virtqueue
     312                 :            :  * \param req_idx descriptor index
     313                 :            :  * \param desc pointer to be set to the descriptor
     314                 :            :  * \param desc_table descriptor table to be used with
     315                 :            :  * \c spdk_vhost_vring_desc_get_next. This might be either
     316                 :            :  * \c NULL or per-chain indirect table.
     317                 :            :  * \param desc_table_size size of the *desc_table*
     318                 :            :  * \return 0 on success, -1 if given index is invalid.
     319                 :            :  * If -1 is returned, the content of params is undefined.
     320                 :            :  */
     321                 :            : int vhost_vq_get_desc_packed(struct spdk_vhost_session *vsession,
     322                 :            :                              struct spdk_vhost_virtqueue *virtqueue,
     323                 :            :                              uint16_t req_idx, struct vring_packed_desc **desc,
     324                 :            :                              struct vring_packed_desc **desc_table, uint32_t *desc_table_size);
     325                 :            : 
     326                 :            : int vhost_inflight_queue_get_desc(struct spdk_vhost_session *vsession,
     327                 :            :                                   spdk_vhost_inflight_desc *desc_array,
     328                 :            :                                   uint16_t req_idx, spdk_vhost_inflight_desc **desc,
     329                 :            :                                   struct vring_packed_desc  **desc_table, uint32_t *desc_table_size);
     330                 :            : 
     331                 :            : /**
     332                 :            :  * Send IRQ/call client (if pending) for \c vq.
     333                 :            :  * \param vsession vhost session
     334                 :            :  * \param vq virtqueue
     335                 :            :  * \return
     336                 :            :  *   0 - if no interrupt was signalled
     337                 :            :  *   1 - if interrupt was signalled
     338                 :            :  */
     339                 :            : int vhost_vq_used_signal(struct spdk_vhost_session *vsession, struct spdk_vhost_virtqueue *vq);
     340                 :            : 
     341                 :            : /**
     342                 :            :  * Send IRQs for the queue that need to be signaled.
     343                 :            :  * \param vq virtqueue
     344                 :            :  */
     345                 :            : void vhost_session_vq_used_signal(struct spdk_vhost_virtqueue *virtqueue);
     346                 :            : 
     347                 :            : void vhost_vq_used_ring_enqueue(struct spdk_vhost_session *vsession,
     348                 :            :                                 struct spdk_vhost_virtqueue *vq,
     349                 :            :                                 uint16_t id, uint32_t len);
     350                 :            : 
     351                 :            : /**
     352                 :            :  * Enqueue the entry to the used ring when device complete the request.
     353                 :            :  * \param vsession vhost session
     354                 :            :  * \param vq virtqueue
     355                 :            :  * \req_idx descriptor index. It's the first index of this descriptor chain.
     356                 :            :  * \num_descs descriptor count. It's the count of the number of buffers in the chain.
     357                 :            :  * \buffer_id descriptor buffer ID.
     358                 :            :  * \length device write length. Specify the length of the buffer that has been initialized
     359                 :            :  * (written to) by the device
     360                 :            :  * \inflight_head the head idx of this IO inflight desc chain.
     361                 :            :  */
     362                 :            : void vhost_vq_packed_ring_enqueue(struct spdk_vhost_session *vsession,
     363                 :            :                                   struct spdk_vhost_virtqueue *virtqueue,
     364                 :            :                                   uint16_t num_descs, uint16_t buffer_id,
     365                 :            :                                   uint32_t length, uint16_t inflight_head);
     366                 :            : 
     367                 :            : /**
     368                 :            :  * Get subsequent descriptor from given table.
     369                 :            :  * \param desc current descriptor, will be set to the
     370                 :            :  * next descriptor (NULL in case this is the last
     371                 :            :  * descriptor in the chain or the next desc is invalid)
     372                 :            :  * \param desc_table descriptor table
     373                 :            :  * \param desc_table_size size of the *desc_table*
     374                 :            :  * \return 0 on success, -1 if given index is invalid
     375                 :            :  * The *desc* param will be set regardless of the
     376                 :            :  * return value.
     377                 :            :  */
     378                 :            : int vhost_vring_desc_get_next(struct vring_desc **desc,
     379                 :            :                               struct vring_desc *desc_table, uint32_t desc_table_size);
     380                 :            : static inline bool
     381                 :   25314560 : vhost_vring_desc_is_wr(struct vring_desc *cur_desc)
     382                 :            : {
     383                 :   25314560 :         return !!(cur_desc->flags & VRING_DESC_F_WRITE);
     384                 :            : }
     385                 :            : 
     386                 :            : int vhost_vring_desc_to_iov(struct spdk_vhost_session *vsession, struct iovec *iov,
     387                 :            :                             uint16_t *iov_index, const struct vring_desc *desc);
     388                 :            : 
     389                 :            : bool vhost_vq_packed_ring_is_avail(struct spdk_vhost_virtqueue *virtqueue);
     390                 :            : 
     391                 :            : /**
     392                 :            :  * Get subsequent descriptor from vq or desc table.
     393                 :            :  * \param desc current descriptor, will be set to the
     394                 :            :  * next descriptor (NULL in case this is the last
     395                 :            :  * descriptor in the chain or the next desc is invalid)
     396                 :            :  * \req_idx index of current desc, will be set to the next
     397                 :            :  * index. If desc_table != NULL the req_idx is the the vring index
     398                 :            :  * or the req_idx is the desc_table index.
     399                 :            :  * \param desc_table descriptor table
     400                 :            :  * \param desc_table_size size of the *desc_table*
     401                 :            :  * \return 0 on success, -1 if given index is invalid
     402                 :            :  * The *desc* param will be set regardless of the
     403                 :            :  * return value.
     404                 :            :  */
     405                 :            : int vhost_vring_packed_desc_get_next(struct vring_packed_desc **desc, uint16_t *req_idx,
     406                 :            :                                      struct spdk_vhost_virtqueue *vq,
     407                 :            :                                      struct vring_packed_desc *desc_table,
     408                 :            :                                      uint32_t desc_table_size);
     409                 :            : 
     410                 :            : bool vhost_vring_packed_desc_is_wr(struct vring_packed_desc *cur_desc);
     411                 :            : 
     412                 :            : int vhost_vring_packed_desc_to_iov(struct spdk_vhost_session *vsession, struct iovec *iov,
     413                 :            :                                    uint16_t *iov_index, const struct vring_packed_desc *desc);
     414                 :            : 
     415                 :            : bool vhost_vring_inflight_desc_is_wr(spdk_vhost_inflight_desc *cur_desc);
     416                 :            : 
     417                 :            : int vhost_vring_inflight_desc_to_iov(struct spdk_vhost_session *vsession, struct iovec *iov,
     418                 :            :                                      uint16_t *iov_index, const spdk_vhost_inflight_desc *desc);
     419                 :            : 
     420                 :            : uint16_t vhost_vring_packed_desc_get_buffer_id(struct spdk_vhost_virtqueue *vq, uint16_t req_idx,
     421                 :            :                 uint16_t *num_descs);
     422                 :            : 
     423                 :            : static inline bool
     424                 :            : __attribute__((always_inline))
     425                 :            : vhost_dev_has_feature(struct spdk_vhost_session *vsession, unsigned feature_id)
     426                 :            : {
     427   [ -  +  -  +  :   19615961 :         return vsession->negotiated_features & (1ULL << feature_id);
                   -  + ]
     428                 :            : }
     429                 :            : 
     430                 :            : int vhost_scsi_controller_start(const char *name);
     431                 :            : 
     432                 :            : int vhost_dev_register(struct spdk_vhost_dev *vdev, const char *name, const char *mask_str,
     433                 :            :                        const struct spdk_json_val *params, const struct spdk_vhost_dev_backend *backend,
     434                 :            :                        const struct spdk_vhost_user_dev_backend *user_backend, bool delay);
     435                 :            : 
     436                 :            : int vhost_dev_unregister(struct spdk_vhost_dev *vdev);
     437                 :            : 
     438                 :            : void vhost_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w);
     439                 :            : 
     440                 :            : /*
     441                 :            :  * Set vhost session to run in interrupt or poll mode
     442                 :            :  */
     443                 :            : void vhost_user_session_set_interrupt_mode(struct spdk_vhost_session *vsession,
     444                 :            :                 bool interrupt_mode);
     445                 :            : 
     446                 :            : /*
     447                 :            :  * Memory registration functions used in start/stop device callbacks
     448                 :            :  */
     449                 :            : void vhost_session_mem_register(struct rte_vhost_memory *mem);
     450                 :            : void vhost_session_mem_unregister(struct rte_vhost_memory *mem);
     451                 :            : 
     452                 :            : /*
     453                 :            :  * Call a function for each session of the provided vhost device.
     454                 :            :  * The function will be called one-by-one on each session's thread.
     455                 :            :  *
     456                 :            :  * \param vdev vhost device
     457                 :            :  * \param fn function to call on each session's thread
     458                 :            :  * \param cpl_fn function to be called at the end of the iteration on
     459                 :            :  * the vhost management thread.
     460                 :            :  * Optional, can be NULL.
     461                 :            :  * \param arg additional argument to the both callbacks
     462                 :            :  */
     463                 :            : void vhost_user_dev_foreach_session(struct spdk_vhost_dev *dev,
     464                 :            :                                     spdk_vhost_session_fn fn,
     465                 :            :                                     spdk_vhost_dev_fn cpl_fn,
     466                 :            :                                     void *arg);
     467                 :            : 
     468                 :            : /**
     469                 :            :  * Finish a blocking vhost_user_wait_for_session_stop() call and finally
     470                 :            :  * stop the session. This must be called on the session's lcore which
     471                 :            :  * used to receive all session-related messages (e.g. from
     472                 :            :  * vhost_user_dev_foreach_session()). After this call, the session-
     473                 :            :  * related messages will be once again processed by any arbitrary thread.
     474                 :            :  *
     475                 :            :  * Must be called under the vhost user device's session access lock.
     476                 :            :  *
     477                 :            :  * \param vsession vhost session
     478                 :            :  * \param response return code
     479                 :            :  */
     480                 :            : void vhost_user_session_stop_done(struct spdk_vhost_session *vsession, int response);
     481                 :            : 
     482                 :            : struct spdk_vhost_session *vhost_session_find_by_vid(int vid);
     483                 :            : void vhost_session_install_rte_compat_hooks(struct spdk_vhost_session *vsession);
     484                 :            : int vhost_register_unix_socket(const char *path, const char *ctrl_name,
     485                 :            :                                uint64_t virtio_features, uint64_t disabled_features, uint64_t protocol_features);
     486                 :            : int vhost_driver_unregister(const char *path);
     487                 :            : int vhost_get_mem_table(int vid, struct rte_vhost_memory **mem);
     488                 :            : int vhost_get_negotiated_features(int vid, uint64_t *negotiated_features);
     489                 :            : 
     490                 :            : int remove_vhost_controller(struct spdk_vhost_dev *vdev);
     491                 :            : 
     492                 :            : struct spdk_io_channel *vhost_blk_get_io_channel(struct spdk_vhost_dev *vdev);
     493                 :            : void vhost_blk_put_io_channel(struct spdk_io_channel *ch);
     494                 :            : 
     495                 :            : /* The spdk_bdev pointer should only be used to retrieve
     496                 :            :  * the device properties, ex. number of blocks or I/O type supported. */
     497                 :            : struct spdk_bdev *vhost_blk_get_bdev(struct spdk_vhost_dev *vdev);
     498                 :            : 
     499                 :            : /* Function calls from vhost.c to rte_vhost_user.c,
     500                 :            :  * shall removed once virtio transport abstraction is complete. */
     501                 :            : int vhost_user_session_set_coalescing(struct spdk_vhost_dev *dev,
     502                 :            :                                       struct spdk_vhost_session *vsession, void *ctx);
     503                 :            : int vhost_user_dev_set_coalescing(struct spdk_vhost_user_dev *user_dev, uint32_t delay_base_us,
     504                 :            :                                   uint32_t iops_threshold);
     505                 :            : int vhost_user_dev_create(struct spdk_vhost_dev *vdev, const char *name,
     506                 :            :                           struct spdk_cpuset *cpumask,
     507                 :            :                           const struct spdk_vhost_user_dev_backend *user_backend, bool dealy);
     508                 :            : int vhost_user_dev_init(struct spdk_vhost_dev *vdev, const char *name,
     509                 :            :                         struct spdk_cpuset *cpumask, const struct spdk_vhost_user_dev_backend *user_backend);
     510                 :            : int vhost_user_dev_start(struct spdk_vhost_dev *vdev);
     511                 :            : int vhost_user_dev_unregister(struct spdk_vhost_dev *vdev);
     512                 :            : int vhost_user_init(void);
     513                 :            : void vhost_user_fini(spdk_vhost_fini_cb vhost_cb);
     514                 :            : int vhost_user_set_coalescing(struct spdk_vhost_dev *vdev, uint32_t delay_base_us,
     515                 :            :                               uint32_t iops_threshold);
     516                 :            : void vhost_user_get_coalescing(struct spdk_vhost_dev *vdev, uint32_t *delay_base_us,
     517                 :            :                                uint32_t *iops_threshold);
     518                 :            : 
     519                 :            : int virtio_blk_construct_ctrlr(struct spdk_vhost_dev *vdev, const char *address,
     520                 :            :                                struct spdk_cpuset *cpumask, const struct spdk_json_val *params,
     521                 :            :                                const struct spdk_vhost_user_dev_backend *user_backend);
     522                 :            : int virtio_blk_destroy_ctrlr(struct spdk_vhost_dev *vdev);
     523                 :            : 
     524                 :            : struct spdk_vhost_blk_task;
     525                 :            : 
     526                 :            : typedef void (*virtio_blk_request_cb)(uint8_t status, struct spdk_vhost_blk_task *task,
     527                 :            :                                       void *cb_arg);
     528                 :            : 
     529                 :            : struct spdk_vhost_blk_task {
     530                 :            :         struct spdk_bdev_io *bdev_io;
     531                 :            :         virtio_blk_request_cb cb;
     532                 :            :         void *cb_arg;
     533                 :            : 
     534                 :            :         volatile uint8_t *status;
     535                 :            : 
     536                 :            :         /* for io wait */
     537                 :            :         struct spdk_bdev_io_wait_entry bdev_io_wait;
     538                 :            :         struct spdk_io_channel *bdev_io_wait_ch;
     539                 :            :         struct spdk_vhost_dev *bdev_io_wait_vdev;
     540                 :            : 
     541                 :            :         /** Number of bytes that were written. */
     542                 :            :         uint32_t used_len;
     543                 :            :         uint16_t iovcnt;
     544                 :            :         struct iovec iovs[SPDK_VHOST_IOVS_MAX];
     545                 :            : 
     546                 :            :         /** Size of whole payload in bytes */
     547                 :            :         uint32_t payload_size;
     548                 :            : };
     549                 :            : 
     550                 :            : int virtio_blk_process_request(struct spdk_vhost_dev *vdev, struct spdk_io_channel *ch,
     551                 :            :                                struct spdk_vhost_blk_task *task, virtio_blk_request_cb cb, void *cb_arg);
     552                 :            : 
     553                 :            : typedef void (*bdev_event_cb_complete)(struct spdk_vhost_dev *vdev, void *ctx);
     554                 :            : 
     555                 :            : #define SPDK_VIRTIO_BLK_TRSTRING_MAX_LEN 32
     556                 :            : 
     557                 :            : struct spdk_virtio_blk_transport_ops {
     558                 :            :         /**
     559                 :            :          * Transport name
     560                 :            :          */
     561                 :            :         char name[SPDK_VIRTIO_BLK_TRSTRING_MAX_LEN];
     562                 :            : 
     563                 :            :         /**
     564                 :            :          * Create a transport for the given transport opts
     565                 :            :          */
     566                 :            :         struct spdk_virtio_blk_transport *(*create)(const struct spdk_json_val *params);
     567                 :            : 
     568                 :            :         /**
     569                 :            :          * Dump transport-specific opts into JSON
     570                 :            :          */
     571                 :            :         void (*dump_opts)(struct spdk_virtio_blk_transport *transport, struct spdk_json_write_ctx *w);
     572                 :            : 
     573                 :            :         /**
     574                 :            :          * Destroy the transport
     575                 :            :          */
     576                 :            :         int (*destroy)(struct spdk_virtio_blk_transport *transport,
     577                 :            :                        spdk_vhost_fini_cb cb_fn);
     578                 :            : 
     579                 :            :         /**
     580                 :            :          * Create vhost block controller
     581                 :            :          */
     582                 :            :         int (*create_ctrlr)(struct spdk_vhost_dev *vdev, struct spdk_cpuset *cpumask,
     583                 :            :                             const char *address, const struct spdk_json_val *params,
     584                 :            :                             void *custom_opts);
     585                 :            : 
     586                 :            :         /**
     587                 :            :          * Destroy vhost block controller
     588                 :            :          */
     589                 :            :         int (*destroy_ctrlr)(struct spdk_vhost_dev *vdev);
     590                 :            : 
     591                 :            :         /*
     592                 :            :          * Signal removal of the bdev.
     593                 :            :          */
     594                 :            :         void (*bdev_event)(enum spdk_bdev_event_type type, struct spdk_vhost_dev *vdev,
     595                 :            :                            bdev_event_cb_complete cb, void *cb_arg);
     596                 :            : 
     597                 :            :         /**
     598                 :            :          * Set coalescing parameters.
     599                 :            :          */
     600                 :            :         int (*set_coalescing)(struct spdk_vhost_dev *vdev, uint32_t delay_base_us,
     601                 :            :                               uint32_t iops_threshold);
     602                 :            : 
     603                 :            :         /**
     604                 :            :          * Get coalescing parameters.
     605                 :            :          */
     606                 :            :         void (*get_coalescing)(struct spdk_vhost_dev *vdev, uint32_t *delay_base_us,
     607                 :            :                                uint32_t *iops_threshold);
     608                 :            : };
     609                 :            : 
     610                 :            : struct spdk_virtio_blk_transport {
     611                 :            :         const struct spdk_virtio_blk_transport_ops      *ops;
     612                 :            :         TAILQ_ENTRY(spdk_virtio_blk_transport)          tailq;
     613                 :            : };
     614                 :            : 
     615                 :            : struct virtio_blk_transport_ops_list_element {
     616                 :            :         struct spdk_virtio_blk_transport_ops                    ops;
     617                 :            :         TAILQ_ENTRY(virtio_blk_transport_ops_list_element)      link;
     618                 :            : };
     619                 :            : 
     620                 :            : void virtio_blk_transport_register(const struct spdk_virtio_blk_transport_ops *ops);
     621                 :            : int virtio_blk_transport_create(const char *transport_name, const struct spdk_json_val *params);
     622                 :            : int virtio_blk_transport_destroy(struct spdk_virtio_blk_transport *transport,
     623                 :            :                                  spdk_vhost_fini_cb cb_fn);
     624                 :            : struct spdk_virtio_blk_transport *virtio_blk_transport_get_first(void);
     625                 :            : struct spdk_virtio_blk_transport *virtio_blk_transport_get_next(
     626                 :            :         struct spdk_virtio_blk_transport *transport);
     627                 :            : void virtio_blk_transport_dump_opts(struct spdk_virtio_blk_transport *transport,
     628                 :            :                                     struct spdk_json_write_ctx *w);
     629                 :            : struct spdk_virtio_blk_transport *virtio_blk_tgt_get_transport(const char *transport_name);
     630                 :            : const struct spdk_virtio_blk_transport_ops *virtio_blk_get_transport_ops(
     631                 :            :         const char *transport_name);
     632                 :            : 
     633                 :            : void vhost_session_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w);
     634                 :            : 
     635                 :            : /*
     636                 :            :  * Macro used to register new transports.
     637                 :            :  */
     638                 :            : #define SPDK_VIRTIO_BLK_TRANSPORT_REGISTER(name, transport_ops) \
     639                 :            : static void __attribute__((constructor)) _virtio_blk_transport_register_##name(void) \
     640                 :            : { \
     641                 :            :         virtio_blk_transport_register(transport_ops); \
     642                 :            : }
     643                 :            : 
     644                 :            : #endif /* SPDK_VHOST_INTERNAL_H */

Generated by: LCOV version 1.14