cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

timer.c (3001B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * linux/net/sunrpc/timer.c
      4 *
      5 * Estimate RPC request round trip time.
      6 *
      7 * Based on packet round-trip and variance estimator algorithms described
      8 * in appendix A of "Congestion Avoidance and Control" by Van Jacobson
      9 * and Michael J. Karels (ACM Computer Communication Review; Proceedings
     10 * of the Sigcomm '88 Symposium in Stanford, CA, August, 1988).
     11 *
     12 * This RTT estimator is used only for RPC over datagram protocols.
     13 *
     14 * Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no>
     15 */
     16
     17#include <asm/param.h>
     18
     19#include <linux/types.h>
     20#include <linux/unistd.h>
     21#include <linux/module.h>
     22
     23#include <linux/sunrpc/clnt.h>
     24
     25#define RPC_RTO_MAX (60*HZ)
     26#define RPC_RTO_INIT (HZ/5)
     27#define RPC_RTO_MIN (HZ/10)
     28
     29/**
     30 * rpc_init_rtt - Initialize an RPC RTT estimator context
     31 * @rt: context to initialize
     32 * @timeo: initial timeout value, in jiffies
     33 *
     34 */
     35void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo)
     36{
     37	unsigned long init = 0;
     38	unsigned int i;
     39
     40	rt->timeo = timeo;
     41
     42	if (timeo > RPC_RTO_INIT)
     43		init = (timeo - RPC_RTO_INIT) << 3;
     44	for (i = 0; i < 5; i++) {
     45		rt->srtt[i] = init;
     46		rt->sdrtt[i] = RPC_RTO_INIT;
     47		rt->ntimeouts[i] = 0;
     48	}
     49}
     50EXPORT_SYMBOL_GPL(rpc_init_rtt);
     51
     52/**
     53 * rpc_update_rtt - Update an RPC RTT estimator context
     54 * @rt: context to update
     55 * @timer: timer array index (request type)
     56 * @m: recent actual RTT, in jiffies
     57 *
     58 * NB: When computing the smoothed RTT and standard deviation,
     59 *     be careful not to produce negative intermediate results.
     60 */
     61void rpc_update_rtt(struct rpc_rtt *rt, unsigned int timer, long m)
     62{
     63	long *srtt, *sdrtt;
     64
     65	if (timer-- == 0)
     66		return;
     67
     68	/* jiffies wrapped; ignore this one */
     69	if (m < 0)
     70		return;
     71
     72	if (m == 0)
     73		m = 1L;
     74
     75	srtt = (long *)&rt->srtt[timer];
     76	m -= *srtt >> 3;
     77	*srtt += m;
     78
     79	if (m < 0)
     80		m = -m;
     81
     82	sdrtt = (long *)&rt->sdrtt[timer];
     83	m -= *sdrtt >> 2;
     84	*sdrtt += m;
     85
     86	/* Set lower bound on the variance */
     87	if (*sdrtt < RPC_RTO_MIN)
     88		*sdrtt = RPC_RTO_MIN;
     89}
     90EXPORT_SYMBOL_GPL(rpc_update_rtt);
     91
     92/**
     93 * rpc_calc_rto - Provide an estimated timeout value
     94 * @rt: context to use for calculation
     95 * @timer: timer array index (request type)
     96 *
     97 * Estimate RTO for an NFS RPC sent via an unreliable datagram.  Use
     98 * the mean and mean deviation of RTT for the appropriate type of RPC
     99 * for frequently issued RPCs, and a fixed default for the others.
    100 *
    101 * The justification for doing "other" this way is that these RPCs
    102 * happen so infrequently that timer estimation would probably be
    103 * stale.  Also, since many of these RPCs are non-idempotent, a
    104 * conservative timeout is desired.
    105 *
    106 * getattr, lookup,
    107 * read, write, commit     - A+4D
    108 * other                   - timeo
    109 */
    110unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned int timer)
    111{
    112	unsigned long res;
    113
    114	if (timer-- == 0)
    115		return rt->timeo;
    116
    117	res = ((rt->srtt[timer] + 7) >> 3) + rt->sdrtt[timer];
    118	if (res > RPC_RTO_MAX)
    119		res = RPC_RTO_MAX;
    120
    121	return res;
    122}
    123EXPORT_SYMBOL_GPL(rpc_calc_rto);