thread: add spdk_thread_set_interrupt_mode func
spdk_thread_set_interrupt_mode can get spdk_thread run between intr and poll mode. It is only valid when thread interrupt facility is enabled by spdk_interrupt_mode_enable(). Currently, this function is limited that no poller is registered to the spdk_thread. Change-Id: Iba54accd5976beb6f6e155014903928ce2858e36 Signed-off-by: Liu Xiaodong <xiaodong.liu@intel.com> Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6708 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
7ae061d1ea
commit
2d52c6a15b
@ -48,6 +48,12 @@ Removed the `pci_whitelist`, `pci_blacklist` and `master_core` members of struct
|
||||
Removed the `config_file`, `max_delay_us`, `pci_whitelist`
|
||||
and `pci_blacklist` members of struct `spdk_app_opts`.
|
||||
|
||||
### thread
|
||||
|
||||
Added `spdk_thread_set_interrupt_mode` function in order to set present spdk_thead into
|
||||
interrupt mode or back to poll mode. It is valid only when thread interrupt facility is
|
||||
enabled by spdk_interrupt_mode_enable().
|
||||
|
||||
### iscsi
|
||||
|
||||
A security vulnerability has been identified and fixed in the SPDK iSCSI target.
|
||||
|
@ -513,6 +513,16 @@ int spdk_thread_send_critical_msg(struct spdk_thread *thread, spdk_msg_fn fn);
|
||||
*/
|
||||
void spdk_for_each_thread(spdk_msg_fn fn, void *ctx, spdk_msg_fn cpl);
|
||||
|
||||
/**
|
||||
* Set current spdk_thread into interrupt mode or back to poll mode.
|
||||
*
|
||||
* Only valid when thread interrupt facility is enabled by
|
||||
* spdk_interrupt_mode_enable().
|
||||
*
|
||||
* \param enable_interrupt Set interrupt mode for true, or poll mode for false
|
||||
*/
|
||||
void spdk_thread_set_interrupt_mode(bool enable_interrupt);
|
||||
|
||||
/**
|
||||
* Register a poller on the current thread.
|
||||
*
|
||||
|
@ -29,6 +29,7 @@
|
||||
spdk_thread_send_msg;
|
||||
spdk_thread_send_critical_msg;
|
||||
spdk_for_each_thread;
|
||||
spdk_thread_set_interrupt_mode;
|
||||
spdk_poller_register;
|
||||
spdk_poller_register_named;
|
||||
spdk_poller_unregister;
|
||||
|
@ -720,6 +720,7 @@ spdk_thread_poll(struct spdk_thread *thread, uint32_t max_msgs, uint64_t now)
|
||||
{
|
||||
struct spdk_thread *orig_thread;
|
||||
int rc;
|
||||
uint64_t notify = 1;
|
||||
|
||||
orig_thread = _get_thread();
|
||||
tls_thread = thread;
|
||||
@ -730,9 +731,25 @@ spdk_thread_poll(struct spdk_thread *thread, uint32_t max_msgs, uint64_t now)
|
||||
|
||||
if (spdk_likely(!thread->in_interrupt)) {
|
||||
rc = thread_poll(thread, max_msgs, now);
|
||||
if (spdk_unlikely(thread->in_interrupt)) {
|
||||
/* The thread transitioned to interrupt mode during the above poll.
|
||||
* Poll it one more time in case that during the transition time
|
||||
* there is msg received without notification.
|
||||
*/
|
||||
rc = thread_poll(thread, max_msgs, now);
|
||||
}
|
||||
} else {
|
||||
/* Non-block wait on thread's fd_group */
|
||||
rc = spdk_fd_group_wait(thread->fgrp, 0);
|
||||
if (spdk_unlikely(!thread->in_interrupt)) {
|
||||
/* The thread transitioned to poll mode in a msg during the above processing.
|
||||
* Clear msg_fd since thread messages will be polled directly in poll mode.
|
||||
*/
|
||||
rc = read(thread->msg_fd, ¬ify, sizeof(notify));
|
||||
if (rc < 0 && errno != EAGAIN) {
|
||||
SPDK_ERRLOG("failed to acknowledge msg queue: %s.\n", spdk_strerror(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -889,6 +906,10 @@ thread_send_msg_notification(const struct spdk_thread *target_thread)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* When each spdk_thread can switch between poll and interrupt mode dynamically,
|
||||
* after sending thread msg, it is necessary to check whether target thread runs in
|
||||
* interrupt mode and then decide whether do event notification.
|
||||
*/
|
||||
if (spdk_unlikely(target_thread->in_interrupt)) {
|
||||
rc = write(target_thread->msg_fd, ¬ify, sizeof(notify));
|
||||
if (rc < 0) {
|
||||
@ -1334,6 +1355,29 @@ spdk_for_each_thread(spdk_msg_fn fn, void *ctx, spdk_msg_fn cpl)
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
void
|
||||
spdk_thread_set_interrupt_mode(bool enable_interrupt)
|
||||
{
|
||||
struct spdk_thread *thread = _get_thread();
|
||||
|
||||
assert(thread);
|
||||
assert(spdk_interrupt_mode_is_enabled());
|
||||
|
||||
if (thread->in_interrupt == enable_interrupt) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Currently, only spdk_thread without pollers can set interrupt mode.
|
||||
* TODO: remove it after adding interrupt mode switch into poller.
|
||||
*/
|
||||
assert(TAILQ_EMPTY(&thread->timed_pollers));
|
||||
assert(TAILQ_EMPTY(&thread->active_pollers));
|
||||
assert(TAILQ_EMPTY(&thread->paused_pollers));
|
||||
|
||||
thread->in_interrupt = enable_interrupt;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
spdk_io_device_register(void *io_device, spdk_io_channel_create_cb create_cb,
|
||||
spdk_io_channel_destroy_cb destroy_cb, uint32_t ctx_size,
|
||||
|
Loading…
Reference in New Issue
Block a user