Currently, UBLK_IO_REGISTER_IO_BUF and UBLK_IO_UNREGISTER_IO_BUF are only permitted on the ublk_io's daemon task. But this restriction is unnecessary. ublk_register_io_buf() calls __ublk_check_and_get_req() to look up the request from the tagset and atomically take a reference on the request without accessing the ublk_io. ublk_unregister_io_buf() doesn't use the q_id or tag at all. So allow these opcodes even on tasks other than io->task. Handle UBLK_IO_UNREGISTER_IO_BUF before obtaining the ubq and io since the buffer index being unregistered is not necessarily related to the specified q_id and tag. Add a feature flag UBLK_F_BUF_REG_OFF_DAEMON that userspace can use to determine whether the kernel supports off-daemon buffer registration.
Showing the changes to include (1 of 2 files). Show all
Unified · Split
| @@ -301,6 +301,16 @@ · 300 unmodified lines | |||
| 301 | */ | 301 | */ |
| 302 | #define UBLK_F_PER_IO_DAEMON (1ULL << 13) | 302 | #define UBLK_F_PER_IO_DAEMON (1ULL << 13) |
| 303 | 303 | ||
| 304 | /* | ||
| 305 | * If this feature is set, UBLK_U_IO_REGISTER_IO_BUF/UBLK_U_IO_UNREGISTER_IO_BUF | ||
| 306 | * can be issued for an I/O on any task. q_id and tag are also ignored in | ||
| 307 | * UBLK_U_IO_UNREGISTER_IO_BUF's ublksrv_io_cmd. | ||
| 308 | * If it is unset, zero-copy buffers can only be registered and unregistered by | ||
| 309 | * the I/O's daemon task. The q_id and tag of the registered buffer are required | ||
| 310 | * in UBLK_U_IO_UNREGISTER_IO_BUF's ublksrv_io_cmd. | ||
| 311 | */ | ||
| 312 | #define UBLK_F_BUF_REG_OFF_DAEMON (1ULL << 14) | ||
| 313 | |||
| 304 | /* device state */ | 314 | /* device state */ |
| 305 | #define UBLK_S_DEV_DEAD 0 | 315 | #define UBLK_S_DEV_DEAD 0 |
| 306 | #define UBLK_S_DEV_LIVE 1 | 316 | #define UBLK_S_DEV_LIVE 1 |