Commit 2d52c6a1 authored by Liu Xiaodong's avatar Liu Xiaodong Committed by Tomasz Zawadzki
Browse files

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: default avatarLiu Xiaodong <xiaodong.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6708


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
parent 7ae061d1
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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.
+10 −0
Original line number Diff line number Diff line
@@ -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.
 *
+1 −0
Original line number Diff line number Diff line
@@ -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;
+44 −0
Original line number Diff line number Diff line
@@ -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, &notify, 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, &notify, 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,