// SPDX-License-Identifier: GPL-2.0-only/* * linux/net/sunrpc/sched.c * * Scheduling for synchronous and asynchronous RPC requests. * * Copyright (C) 1996 Olaf Kirch, <okir@monad.swb.de> * * TCP NFS related read + write fixes * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie> */#include<linux/module.h>#include<linux/sched.h>#include<linux/interrupt.h>#include<linux/slab.h>#include<linux/mempool.h>#include<linux/smp.h>#include<linux/spinlock.h>#include<linux/mutex.h>#include<linux/freezer.h>#include<linux/sched/mm.h>#include<linux/sunrpc/clnt.h>#include<linux/sunrpc/metrics.h>#include"sunrpc.h"#define CREATE_TRACE_POINTS#include<trace/events/sunrpc.h>/* * RPC slabs and memory pools */#define RPC_BUFFER_MAXSIZE (2048)#define RPC_BUFFER_POOLSIZE (8)#define RPC_TASK_POOLSIZE (8)staticstructkmem_cache*rpc_task_slabp__read_mostly;staticstructkmem_cache*rpc_buffer_slabp__read_mostly;staticmempool_t*rpc_task_mempool__read_mostly;staticmempool_t*rpc_buffer_mempool__read_mostly;staticvoidrpc_async_schedule(structwork_struct*);staticvoidrpc_release_task(structrpc_task*task);staticvoid__rpc_queue_timer_fn(structwork_struct*);/* * RPC tasks sit here while waiting for conditions to improve. */staticstructrpc_wait_queuedelay_queue;/* * rpciod-related stuff */structworkqueue_struct*rpciod_workqueue__read_mostly;structworkqueue_struct*xprtiod_workqueue__read_mostly;EXPORT_SYMBOL_GPL(xprtiod_workqueue);gfp_trpc_task_gfp_mask(void){if(current->flags&PF_WQ_WORKER)returnGFP_KERNEL|__GFP_NORETRY|__GFP_NOWARN;returnGFP_KERNEL;}unsignedlongrpc_task_timeout(conststructrpc_task*task){unsignedlongtimeout=READ_ONCE(task->tk_timeout);if(timeout!=0){unsignedlongnow=jiffies;if(time_before(now,timeout))returntimeout-now;}return0;}EXPORT_SYMBOL_GPL(rpc_task_timeout);/* * Disable the timer for a given RPC task. Should be called with * queue->lock and bh_disabled in order to avoid races within * rpc_run_timer(). */staticvoid__rpc_disable_timer(structrpc_wait_queue*queue,structrpc_task*task){if(list_empty(&task->u.tk_wait.timer_list))return;task->tk_timeout=0;list_del(&task->u.tk_wait.timer_list);if(list_empty(&queue->timer_list.list))cancel_delayed_work(&queue->timer_list.dwork);}staticvoidrpc_set_queue_timer(structrpc_wait_qu