4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <rte_config.h>
37 #include <rte_mempool.h>
39 #include "spdk_internal/log.h"
40 #include "spdk_internal/event.h"
42 #include "spdk/queue.h"
46 #define container_of(ptr, type, member) ({ \
47 typeof(((type *)0)->member) *__mptr = (ptr); \
48 (type *)((char *)__mptr - offsetof(type, member)); })
50 typedef TAILQ_HEAD(, spdk_vhost_task
) need_iovecs_tailq_t
;
52 static struct rte_mempool
*g_task_pool
;
53 static struct rte_mempool
*g_iov_buffer_pool
;
55 static need_iovecs_tailq_t g_need_iovecs
[RTE_MAX_LCORE
];
58 spdk_vhost_task_put(struct spdk_vhost_task
*task
)
60 assert(&task
->scsi
.iov
== task
->scsi
.iovs
);
61 assert(task
->scsi
.iovcnt
== 1);
62 spdk_scsi_task_put(&task
->scsi
);
66 spdk_vhost_task_free_cb(struct spdk_scsi_task
*scsi_task
)
68 struct spdk_vhost_task
*task
= container_of(scsi_task
, struct spdk_vhost_task
, scsi
);
70 rte_mempool_put(g_task_pool
, task
);
73 struct spdk_vhost_task
*
74 spdk_vhost_task_get(uint32_t *owner_task_ctr
)
76 struct spdk_vhost_task
*task
;
79 rc
= rte_mempool_get(g_task_pool
, (void **)&task
);
80 if ((rc
< 0) || !task
) {
81 SPDK_ERRLOG("Unable to get task\n");
82 rte_panic("no memory\n");
85 memset(task
, 0, sizeof(*task
));
86 spdk_scsi_task_construct(&task
->scsi
, owner_task_ctr
, NULL
);
87 task
->scsi
.free_fn
= spdk_vhost_task_free_cb
;
93 spdk_vhost_enqueue_task(struct spdk_vhost_task
*task
)
95 need_iovecs_tailq_t
*tailq
= &g_need_iovecs
[rte_lcore_id()];
97 TAILQ_INSERT_TAIL(tailq
, task
, iovecs_link
);
100 struct spdk_vhost_task
*
101 spdk_vhost_dequeue_task(void)
103 need_iovecs_tailq_t
*tailq
= &g_need_iovecs
[rte_lcore_id()];
104 struct spdk_vhost_task
*task
;
106 if (TAILQ_EMPTY(tailq
))
109 task
= TAILQ_FIRST(tailq
);
110 TAILQ_REMOVE(tailq
, task
, iovecs_link
);
116 spdk_vhost_iovec_alloc(void)
118 struct iovec
*iov
= NULL
;
120 rte_mempool_get(g_iov_buffer_pool
, (void **)&iov
);
125 spdk_vhost_iovec_free(struct iovec
*iov
)
127 rte_mempool_put(g_iov_buffer_pool
, iov
);
131 spdk_vhost_subsystem_init(void)
133 g_task_pool
= rte_mempool_create("vhost task pool", 16384, sizeof(struct spdk_vhost_task
),
134 128, 0, NULL
, NULL
, NULL
, NULL
, SOCKET_ID_ANY
, 0);
136 SPDK_ERRLOG("create task pool failed\n");
140 g_iov_buffer_pool
= rte_mempool_create("vhost iov buffer pool", 2048,
141 VHOST_SCSI_IOVS_LEN
* sizeof(struct iovec
),
142 128, 0, NULL
, NULL
, NULL
, NULL
, SOCKET_ID_ANY
, 0);
143 if (!g_iov_buffer_pool
) {
144 SPDK_ERRLOG("create iov buffer pool failed\n");
148 for (int i
= 0; i
< RTE_MAX_LCORE
; i
++) {
149 TAILQ_INIT(&g_need_iovecs
[i
]);
156 spdk_vhost_subsystem_fini(void)
161 SPDK_SUBSYSTEM_REGISTER(vhost
, spdk_vhost_subsystem_init
, spdk_vhost_subsystem_fini
, NULL
)
162 SPDK_SUBSYSTEM_DEPEND(vhost
, scsi
)