2022-07-12 23:52:38 +03:00
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/file.h>
# include <linux/slab.h>
# include <linux/net.h>
# include <linux/io_uring.h>
# include "io_uring.h"
# include "notif.h"
2022-07-12 23:52:41 +03:00
# include "rsrc.h"
2022-07-12 23:52:38 +03:00
2023-03-27 18:38:15 +03:00
static void io_notif_complete_tw_ext ( struct io_kiocb * notif , struct io_tw_state * ts )
2022-07-12 23:52:38 +03:00
{
2022-07-27 12:30:41 +03:00
struct io_notif_data * nd = io_notif_to_data ( notif ) ;
2022-07-12 23:52:38 +03:00
struct io_ring_ctx * ctx = notif - > ctx ;
2022-11-04 13:59:46 +03:00
if ( nd - > zc_report & & ( nd - > zc_copied | | ! nd - > zc_used ) )
notif - > cqe . res | = IORING_NOTIF_USAGE_ZC_COPIED ;
2022-07-27 12:30:41 +03:00
if ( nd - > account_pages & & ctx - > user ) {
__io_unaccount_mem ( ctx - > user , nd - > account_pages ) ;
nd - > account_pages = 0 ;
2022-07-12 23:52:44 +03:00
}
2023-03-27 18:38:15 +03:00
io_req_task_complete ( notif , ts ) ;
2022-11-04 13:59:45 +03:00
}
2022-11-04 13:59:43 +03:00
static void io_tx_ubuf_callback ( struct sk_buff * skb , struct ubuf_info * uarg ,
bool success )
2022-07-12 23:52:38 +03:00
{
2022-07-27 12:30:41 +03:00
struct io_notif_data * nd = container_of ( uarg , struct io_notif_data , uarg ) ;
struct io_kiocb * notif = cmd_to_io_kiocb ( nd ) ;
2022-07-12 23:52:39 +03:00
2022-11-04 13:59:45 +03:00
if ( refcount_dec_and_test ( & uarg - > refcnt ) )
2023-04-06 16:20:12 +03:00
__io_req_task_work_add ( notif , IOU_F_TWQ_LAZY_WAKE ) ;
2022-11-04 13:59:45 +03:00
}
static void io_tx_ubuf_callback_ext ( struct sk_buff * skb , struct ubuf_info * uarg ,
bool success )
{
struct io_notif_data * nd = container_of ( uarg , struct io_notif_data , uarg ) ;
2022-10-27 21:34:45 +03:00
if ( nd - > zc_report ) {
if ( success & & ! nd - > zc_used & & skb )
WRITE_ONCE ( nd - > zc_used , true ) ;
else if ( ! success & & ! nd - > zc_copied )
WRITE_ONCE ( nd - > zc_copied , true ) ;
}
2022-11-04 13:59:45 +03:00
io_tx_ubuf_callback ( skb , uarg , success ) ;
}
2022-10-27 21:34:45 +03:00
2022-11-04 13:59:45 +03:00
void io_notif_set_extended ( struct io_kiocb * notif )
{
struct io_notif_data * nd = io_notif_to_data ( notif ) ;
2022-11-04 13:59:46 +03:00
if ( nd - > uarg . callback ! = io_tx_ubuf_callback_ext ) {
nd - > account_pages = 0 ;
nd - > zc_report = false ;
nd - > zc_used = false ;
nd - > zc_copied = false ;
nd - > uarg . callback = io_tx_ubuf_callback_ext ;
notif - > io_task_work . func = io_notif_complete_tw_ext ;
}
2022-07-12 23:52:39 +03:00
}
2022-09-01 13:54:04 +03:00
struct io_kiocb * io_alloc_notif ( struct io_ring_ctx * ctx )
2022-07-12 23:52:38 +03:00
__must_hold ( & ctx - > uring_lock )
{
2022-07-27 12:30:41 +03:00
struct io_kiocb * notif ;
struct io_notif_data * nd ;
2023-01-23 17:37:16 +03:00
if ( unlikely ( ! io_alloc_req ( ctx , & notif ) ) )
2022-07-27 12:30:41 +03:00
return NULL ;
notif - > opcode = IORING_OP_NOP ;
notif - > flags = 0 ;
notif - > file = NULL ;
notif - > task = current ;
io_get_task_refs ( 1 ) ;
notif - > rsrc_node = NULL ;
2022-11-04 13:59:46 +03:00
notif - > io_task_work . func = io_req_task_complete ;
2022-07-27 12:30:41 +03:00
nd = io_notif_to_data ( notif ) ;
2023-04-15 16:20:08 +03:00
nd - > uarg . flags = IO_NOTIF_UBUF_FLAGS ;
2022-11-04 13:59:43 +03:00
nd - > uarg . callback = io_tx_ubuf_callback ;
2022-07-27 12:30:41 +03:00
refcount_set ( & nd - > uarg . refcnt , 1 ) ;
2022-07-12 23:52:38 +03:00
return notif ;
}