case io_state_t::drop:
ctx.exit_out_dispatching("dropped", conn);
return seastar::make_ready_future<stop_t>(stop_t::yes);
+ case io_state_t::switched:
+ ctx.exit_out_dispatching("switched", conn);
+ return seastar::make_ready_future<stop_t>(stop_t::yes);
default:
ceph_abort("impossible");
}
handshake_listener->notify_out_fault(
"do_out_dispatch", eptr, states);
} else {
- logger().info("{} do_out_dispatch(): fault at {} -- {}",
- conn, io_state, e.what());
+ if (io_state != io_state_t::switched) {
+ logger().info("{} do_out_dispatch(): fault at {}, {} -- {}",
+ conn, io_state, io_stat_printer{*this}, e.what());
+ } else {
+ logger().info("{} do_out_dispatch(): fault at {} -- {}",
+ conn, io_state, e.what());
+ }
}
return do_out_dispatch(ctx);
handshake_listener->notify_out_fault(
"do_in_dispatch", eptr, states);
} else {
- logger().info("{} do_in_dispatch(): fault at {} -- {}",
- conn, io_state, e_what);
+ if (io_state != io_state_t::switched) {
+ logger().info("{} do_in_dispatch(): fault at {}, {} -- {}",
+ conn, io_state, io_stat_printer{*this}, e_what);
+ } else {
+ logger().info("{} do_in_dispatch(): fault at {} -- {}",
+ conn, io_state, e_what);
+ }
}
}).finally([&ctx] {
ctx.exit_in_dispatching();
).discard_result();
}
+IOHandler::shard_states_ref_t
+IOHandler::shard_states_t::create_from_previous(
+ shard_states_t &prv_states,
+ seastar::shard_id new_sid)
+{
+ auto io_state = prv_states.io_state;
+ assert(io_state != io_state_t::open);
+ auto ret = shard_states_t::create(new_sid, io_state);
+ if (io_state == io_state_t::drop) {
+ // the new gate should not never be used
+ auto fut = ret->gate.close();
+ ceph_assert_always(fut.available());
+ }
+ prv_states.set_io_state(io_state_t::switched);
+ return ret;
+}
+
} // namespace crimson::net
* io behavior accordingly.
*/
enum class io_state_t : uint8_t {
- none, // no IO is possible as the connection is not available to the user yet.
- delay, // IO is delayed until open.
- open, // Dispatch In and Out concurrently.
- drop // Drop IO as the connection is closed.
+ none, // no IO is possible as the connection is not available to the user yet.
+ delay, // IO is delayed until open.
+ open, // Dispatch In and Out concurrently.
+ drop, // Drop IO as the connection is closed.
+ switched // IO is switched to a different core
+ // (is moved to maybe_prv_shard_states)
};
friend class fmt::formatter<io_state_t>;
out_dispatching = true;
return true;
case io_state_t::drop:
+ [[fallthrough]];
+ case io_state_t::switched:
// do not dispatch out
return false;
default:
bool assert_closed_and_exit() const {
assert(seastar::this_shard_id() == sid);
if (gate.is_closed()) {
- ceph_assert_always(io_state == io_state_t::drop);
+ ceph_assert_always(io_state == io_state_t::drop ||
+ io_state == io_state_t::switched);
ceph_assert_always(!out_dispatching);
ceph_assert_always(!out_exit_dispatching);
ceph_assert_always(!in_exit_dispatching);
return std::make_unique<shard_states_t>(sid, state);
}
+ static shard_states_ref_t create_from_previous(
+ shard_states_t &prv_states, seastar::shard_id new_sid);
+
private:
const seastar::shard_id sid;
io_state_t io_state;
case drop:
name = "drop";
break;
+ case switched:
+ name = "switched";
+ break;
}
return formatter<string_view>::format(name, ctx);
}