Home | History | Annotate | Download | only in include
      1 /* SPDX-License-Identifier: GPL-2.0-or-later */
      2 /*
      3  * Copyright (c) 2017-2018 Richard Palethorpe <rpalethorpe (at) suse.com>
      4  */
      5 /**
      6  * @file tst_fuzzy_sync.h
      7  * Fuzzy Synchronisation - abbreviated to fzsync
      8  *
      9  * This library is intended to help reproduce race conditions by synchronising
     10  * two threads at a given place by marking the range a race may occur
     11  * in. Because the exact place where any race occurs is within the kernel,
     12  * and therefore impossible to mark accurately, the library may add randomised
     13  * delays to either thread in order to help find the exact race timing.
     14  *
     15  * Currently only two way races are explicitly supported, that is races
     16  * involving two threads or processes. We refer to the main test thread as
     17  * thread A and the child thread as thread B.
     18  *
     19  * In each thread you need a simple while- or for-loop which the tst_fzsync_*
     20  * functions are called in. In the simplest case thread A will look something
     21  * like:
     22  *
     23  * tst_fzsync_pair_reset(&pair, run_thread_b);
     24  * while (tst_fzsync_run_a(&pair)) {
     25  *	// Perform some setup which must happen before the race
     26  *	tst_fzsync_start_race_a(&pair);
     27  *	// Do some dodgy syscall
     28  *	tst_fzsync_end_race_a(&pair);
     29  * }
     30  *
     31  * Then in thread B (run_thread_b):
     32  *
     33  * while (tst_fzsync_run_b(&pair)) {
     34  *	tst_fzsync_start_race_b(&pair);
     35  *	// Do something which can race with the dodgy syscall in A
     36  *	tst_fzsync_end_race_b(&pair)
     37  * }
     38  *
     39  * The calls to tst_fzsync_start/end_race and tst_fzsync_run_a/b block (at
     40  * least) until both threads have enter them. These functions can only be
     41  * called once for each iteration, but further synchronisation points can be
     42  * added by calling tst_fzsync_wait_a() and tst_fzsync_wait_b() in each
     43  * thread.
     44  *
     45  * The execution of the loops in threads A and B are bounded by both iteration
     46  * count and time. A slow machine is likely to be limited by time and a fast
     47  * one by iteration count. The user can use the -i parameter to run the test
     48  * multiple times or LTP_TIMEOUT_MUL to give the test more time.
     49  *
     50  * It is possible to use the library just for tst_fzsync_pair_wait() to get a
     51  * basic spin wait. However if you are actually testing a race condition then
     52  * it is recommended to use tst_fzsync_start_race_a/b even if the
     53  * randomisation is not needed. It provides some semantic information which
     54  * may be useful in the future.
     55  *
     56  * For a usage example see testcases/cve/cve-2016-7117.c or just run
     57  * 'git grep tst_fuzzy_sync.h'
     58  *
     59  * @sa tst_fzsync_pair
     60  */
     61 
     62 #include <sys/time.h>
     63 #include <time.h>
     64 #include <math.h>
     65 #include <stdlib.h>
     66 #include "tst_atomic.h"
     67 #include "tst_timer.h"
     68 #include "tst_safe_pthread.h"
     69 
     70 #ifndef TST_FUZZY_SYNC_H__
     71 #define TST_FUZZY_SYNC_H__
     72 
     73 /* how much of exec time is sampling allowed to take */
     74 #define SAMPLING_SLICE 0.5f
     75 
     76 /** Some statistics for a variable */
     77 struct tst_fzsync_stat {
     78 	float avg;
     79 	float avg_dev;
     80 	float dev_ratio;
     81 };
     82 
     83 /**
     84  * The state of a two way synchronisation or race.
     85  *
     86  * This contains all the necessary state for approximately synchronising two
     87  * sections of code in different threads.
     88  *
     89  * Some of the fields can be configured before calling
     90  * tst_fzsync_pair_reset(), however this is mainly for debugging purposes. If
     91  * a test requires one of the parameters to be modified, we should consider
     92  * finding a way of automatically selecting an appropriate value at runtime.
     93  *
     94  * Internal fields should only be accessed by library functions.
     95  */
     96 struct tst_fzsync_pair {
     97 	/**
     98 	 * The rate at which old diff samples are forgotten
     99 	 *
    100 	 * Defaults to 0.25.
    101 	 */
    102 	float avg_alpha;
    103 	/** Internal; Thread A start time */
    104 	struct timespec a_start;
    105 	/** Internal; Thread B start time */
    106 	struct timespec b_start;
    107 	/** Internal; Thread A end time */
    108 	struct timespec a_end;
    109 	/** Internal; Thread B end time */
    110 	struct timespec b_end;
    111 	/** Internal; Avg. difference between a_start and b_start */
    112 	struct tst_fzsync_stat diff_ss;
    113 	/** Internal; Avg. difference between a_start and a_end */
    114 	struct tst_fzsync_stat diff_sa;
    115 	/** Internal; Avg. difference between b_start and b_end */
    116 	struct tst_fzsync_stat diff_sb;
    117 	/** Internal; Avg. difference between a_end and b_end */
    118 	struct tst_fzsync_stat diff_ab;
    119 	/** Internal; Number of spins while waiting for the slower thread */
    120 	int spins;
    121 	struct tst_fzsync_stat spins_avg;
    122 	/**
    123 	 * Internal; Number of spins to use in the delay.
    124 	 *
    125 	 * A negative value delays thread A and a positive delays thread B.
    126 	 */
    127 	int delay;
    128 	int delay_bias;
    129 	/**
    130 	 *  Internal; The number of samples left or the sampling state.
    131 	 *
    132 	 *  A positive value is the number of remaining mandatory
    133 	 *  samples. Zero or a negative indicate some other state.
    134 	 */
    135 	int sampling;
    136 	/**
    137 	 * The Minimum number of statistical samples which must be collected.
    138 	 *
    139 	 * The minimum number of iterations which must be performed before a
    140 	 * random delay can be calculated. Defaults to 1024.
    141 	 */
    142 	int min_samples;
    143 	/**
    144 	 * The maximum allowed proportional average deviation.
    145 	 *
    146 	 * A value in the range (0, 1) which gives the maximum average
    147 	 * deviation which must be attained before random delays can be
    148 	 * calculated.
    149 	 *
    150 	 * It is a ratio of (average_deviation / total_time). The default is
    151 	 * 0.1, so this allows an average deviation of at most 10%.
    152 	 */
    153 	float max_dev_ratio;
    154 
    155 	/** Internal; Atomic counter used by fzsync_pair_wait() */
    156 	int a_cntr;
    157 	/** Internal; Atomic counter used by fzsync_pair_wait() */
    158 	int b_cntr;
    159 	/** Internal; Used by tst_fzsync_pair_exit() and fzsync_pair_wait() */
    160 	int exit;
    161 	/**
    162 	 * The maximum desired execution time as a proportion of the timeout
    163 	 *
    164 	 * A value x so that 0 < x < 1 which decides how long the test should
    165 	 * be run for (assuming the loop limit is not exceeded first).
    166 	 *
    167 	 * Defaults to 0.5 (~150 seconds with default timeout).
    168 	 */
    169 	float exec_time_p;
    170 	/** Internal; The test time remaining on tst_fzsync_pair_reset() */
    171 	float exec_time_start;
    172 	/**
    173 	 * The maximum number of iterations to execute during the test
    174 	 *
    175 	 * Defaults to a large number, but not too large.
    176 	 */
    177 	int exec_loops;
    178 	/** Internal; The current loop index  */
    179 	int exec_loop;
    180 	/** Internal; The second thread or 0 */
    181 	pthread_t thread_b;
    182 };
    183 
    184 #define CHK(param, low, hi, def) do {					      \
    185 	pair->param = (pair->param ? pair->param : def);		      \
    186 	if (pair->param < low)						      \
    187 		tst_brk(TBROK, #param " is less than the lower bound " #low); \
    188 	if (pair->param > hi)						      \
    189 		tst_brk(TBROK, #param " is more than the upper bound " #hi);  \
    190 	} while (0)
    191 /**
    192  * Ensures that any Fuzzy Sync parameters are properly set
    193  *
    194  * @relates tst_fzsync_pair
    195  *
    196  * Usually called from the setup function, it sets default parameter values or
    197  * validates any existing non-defaults.
    198  *
    199  * @sa tst_fzsync_pair_reset()
    200  */
    201 static void tst_fzsync_pair_init(struct tst_fzsync_pair *pair)
    202 {
    203 	CHK(avg_alpha, 0, 1, 0.25);
    204 	CHK(min_samples, 20, INT_MAX, 1024);
    205 	CHK(max_dev_ratio, 0, 1, 0.1);
    206 	CHK(exec_time_p, 0, 1, 0.5);
    207 	CHK(exec_loops, 20, INT_MAX, 3000000);
    208 }
    209 #undef CHK
    210 
    211 /**
    212  * Exit and join thread B if necessary.
    213  *
    214  * @relates tst_fzsync_pair
    215  *
    216  * Call this from your cleanup function.
    217  */
    218 static void tst_fzsync_pair_cleanup(struct tst_fzsync_pair *pair)
    219 {
    220 	if (pair->thread_b) {
    221 		tst_atomic_store(1, &pair->exit);
    222 		SAFE_PTHREAD_JOIN(pair->thread_b, NULL);
    223 		pair->thread_b = 0;
    224 	}
    225 }
    226 
    227 /**
    228  * Zero some stat fields
    229  *
    230  * @relates tst_fzsync_stat
    231  */
    232 static void tst_init_stat(struct tst_fzsync_stat *s)
    233 {
    234 	s->avg = 0;
    235 	s->avg_dev = 0;
    236 }
    237 
    238 /**
    239  * Reset or initialise fzsync.
    240  *
    241  * @relates tst_fzsync_pair
    242  * @param pair The state structure initialised with TST_FZSYNC_PAIR_INIT.
    243  * @param run_b The function defining thread B or NULL.
    244  *
    245  * Call this from your main test function (thread A), just before entering the
    246  * main loop. It will (re)set any variables needed by fzsync and (re)start
    247  * thread B using the function provided.
    248  *
    249  * If you need to use fork or clone to start the second thread/process then
    250  * you can pass NULL to run_b and handle starting and stopping thread B
    251  * yourself. You may need to place tst_fzsync_pair in some shared memory as
    252  * well.
    253  *
    254  * @sa tst_fzsync_pair_init()
    255  */
    256 static void tst_fzsync_pair_reset(struct tst_fzsync_pair *pair,
    257 				  void *(*run_b)(void *))
    258 {
    259 	tst_fzsync_pair_cleanup(pair);
    260 
    261 	tst_init_stat(&pair->diff_ss);
    262 	tst_init_stat(&pair->diff_sa);
    263 	tst_init_stat(&pair->diff_sb);
    264 	tst_init_stat(&pair->diff_ab);
    265 	tst_init_stat(&pair->spins_avg);
    266 	pair->delay = 0;
    267 	pair->sampling = pair->min_samples;
    268 
    269 	pair->exec_loop = 0;
    270 
    271 	pair->a_cntr = 0;
    272 	pair->b_cntr = 0;
    273 	pair->exit = 0;
    274 	if (run_b)
    275 		SAFE_PTHREAD_CREATE(&pair->thread_b, 0, run_b, 0);
    276 
    277 	pair->exec_time_start = (float)tst_timeout_remaining();
    278 }
    279 
    280 /**
    281  * Print stat
    282  *
    283  * @relates tst_fzsync_stat
    284  */
    285 static inline void tst_fzsync_stat_info(struct tst_fzsync_stat stat,
    286 					char *unit, char *name)
    287 {
    288 	tst_res(TINFO,
    289 		"%1$-17s: { avg = %3$5.0f%2$s, avg_dev = %4$5.0f%2$s, dev_ratio = %5$.2f }",
    290 		name, unit, stat.avg, stat.avg_dev, stat.dev_ratio);
    291 }
    292 
    293 /**
    294  * Print some synchronisation statistics
    295  *
    296  * @relates tst_fzsync_pair
    297  */
    298 static void tst_fzsync_pair_info(struct tst_fzsync_pair *pair)
    299 {
    300 	tst_res(TINFO, "loop = %d, delay_bias = %d",
    301 		pair->exec_loop, pair->delay_bias);
    302 	tst_fzsync_stat_info(pair->diff_ss, "ns", "start_a - start_b");
    303 	tst_fzsync_stat_info(pair->diff_sa, "ns", "end_a - start_a");
    304 	tst_fzsync_stat_info(pair->diff_sb, "ns", "end_b - start_b");
    305 	tst_fzsync_stat_info(pair->diff_ab, "ns", "end_a - end_b");
    306 	tst_fzsync_stat_info(pair->spins_avg, "  ", "spins");
    307 }
    308 
    309 /** Wraps clock_gettime */
    310 static inline void tst_fzsync_time(struct timespec *t)
    311 {
    312 #ifdef CLOCK_MONOTONIC_RAW
    313 	clock_gettime(CLOCK_MONOTONIC_RAW, t);
    314 #else
    315 	clock_gettime(CLOCK_MONOTONIC, t);
    316 #endif
    317 }
    318 
    319 /**
    320  * Exponential moving average
    321  *
    322  * @param alpha The preference for recent samples over old ones.
    323  * @param sample The current sample
    324  * @param prev_avg The average of the all the previous samples
    325  *
    326  * @return The average including the current sample.
    327  */
    328 static inline float tst_exp_moving_avg(float alpha,
    329 					float sample,
    330 					float prev_avg)
    331 {
    332 	return alpha * sample + (1.0 - alpha) * prev_avg;
    333 }
    334 
    335 /**
    336  * Update a stat with a new sample
    337  *
    338  * @relates tst_fzsync_stat
    339  */
    340 static inline void tst_upd_stat(struct tst_fzsync_stat *s,
    341 				 float alpha,
    342 				 float sample)
    343 {
    344 	s->avg = tst_exp_moving_avg(alpha, sample, s->avg);
    345 	s->avg_dev = tst_exp_moving_avg(alpha,
    346 					fabs(s->avg - sample), s->avg_dev);
    347 	s->dev_ratio = fabs(s->avg ? s->avg_dev / s->avg : 0);
    348 }
    349 
    350 /**
    351  * Update a stat with a new diff sample
    352  *
    353  * @relates tst_fzsync_stat
    354  */
    355 static inline void tst_upd_diff_stat(struct tst_fzsync_stat *s,
    356 				     float alpha,
    357 				     struct timespec t1,
    358 				     struct timespec t2)
    359 {
    360 	tst_upd_stat(s, alpha, tst_timespec_diff_ns(t1, t2));
    361 }
    362 
    363 /**
    364  * Calculate various statistics and the delay
    365  *
    366  * This function helps create the fuzz in fuzzy sync. Imagine we have the
    367  * following timelines in threads A and B:
    368  *
    369  *  start_race_a
    370  *      ^                    end_race_a (a)
    371  *      |                        ^
    372  *      |                        |
    373  *  - --+------------------------+-- - -
    374  *      |        Syscall A       |                 Thread A
    375  *  - --+------------------------+-- - -
    376  *  - --+----------------+-------+-- - -
    377  *      |   Syscall B    | spin  |                 Thread B
    378  *  - --+----------------+-------+-- - -
    379  *      |                |
    380  *      ^                ^
    381  *  start_race_b     end_race_b
    382  *
    383  * Here we have synchronised the calls to syscall A and B with start_race_{a,
    384  * b} so that they happen at approximately the same time in threads A and
    385  * B. If the race condition occurs during the entry code for these two
    386  * functions then we will quickly hit it. If it occurs during the exit code of
    387  * B and mid way through A, then we will quickly hit it.
    388  *
    389  * However if the exit paths of A and B need to be aligned and (end_race_a -
    390  * end_race_b) is large relative to the variation in call times, the
    391  * probability of hitting the race condition is close to zero. To solve this
    392  * scenario (and others) a randomised delay is introduced before the syscalls
    393  * in A and B. Given enough time the following should happen where the exit
    394  * paths are now synchronised:
    395  *
    396  *  start_race_a
    397  *      ^                    end_race_a (a)
    398  *      |                        ^
    399  *      |                        |
    400  *  - --+------------------------+-- - -
    401  *      |        Syscall A       |                 Thread A
    402  *  - --+------------------------+-- - -
    403  *  - --+-------+----------------+-- - -
    404  *      | delay |   Syscall B    |                 Thread B
    405  *  - --+-------+----------------+-- - -
    406  *      |                        |
    407  *      ^                        ^
    408  *  start_race_b             end_race_b
    409  *
    410  * The delay is not introduced immediately and the delay range is only
    411  * calculated once the average relative deviation has dropped below some
    412  * percentage of the total time.
    413  *
    414  * The delay range is chosen so that any point in Syscall A could be
    415  * synchronised with any point in Syscall B using a value from the
    416  * range. Because the delay range may be too large for a linear search, we use
    417  * an evenly distributed random function to pick a value from it.
    418  *
    419  * The delay range goes from positive to negative. A negative delay will delay
    420  * thread A and a positive one will delay thread B. The range is bounded by
    421  * the point where the entry code to Syscall A is synchronised with the exit
    422  * to Syscall B and the entry code to Syscall B is synchronised with the exit
    423  * of A.
    424  *
    425  * In order to calculate the lower bound (the max delay of A) we can simply
    426  * negate the execution time of Syscall B and convert it to a spin count. For
    427  * the upper bound (the max delay of B), we just take the execution time of A
    428  * and convert it to a spin count.
    429  *
    430  * In order to calculate spin count we need to know approximately how long a
    431  * spin takes and divide the delay time with it. We find this by first
    432  * counting how many spins one thread spends waiting for the other during
    433  * end_race[1]. We also know when each syscall exits so we can take the
    434  * difference between the exit times and divide it with the number of spins
    435  * spent waiting.
    436  *
    437  * All the times and counts we use in the calculation are averaged over a
    438  * variable number of iterations. There is an initial sampling period where we
    439  * simply collect time and count samples then calculate their averages. When a
    440  * minimum number of samples have been collected, and if the average deviation
    441  * is below some proportion of the average sample magnitude, then the sampling
    442  * period is ended. On all further iterations a random delay is calculated and
    443  * applied, but the averages are not updated.
    444  *
    445  * [1] This assumes there is always a significant difference. The algorithm
    446  * may fail to introduce a delay (when one is needed) in situations where
    447  * Syscall A and B finish at approximately the same time.
    448  *
    449  * @relates tst_fzsync_pair
    450  */
    451 static void tst_fzsync_pair_update(struct tst_fzsync_pair *pair)
    452 {
    453 	float alpha = pair->avg_alpha;
    454 	float per_spin_time, time_delay;
    455 	float max_dev = pair->max_dev_ratio;
    456 	int over_max_dev;
    457 
    458 	pair->delay = pair->delay_bias;
    459 
    460 	over_max_dev = pair->diff_ss.dev_ratio > max_dev
    461 		|| pair->diff_sa.dev_ratio > max_dev
    462 		|| pair->diff_sb.dev_ratio > max_dev
    463 		|| pair->diff_ab.dev_ratio > max_dev
    464 		|| pair->spins_avg.dev_ratio > max_dev;
    465 
    466 	if (pair->sampling > 0 || over_max_dev) {
    467 		tst_upd_diff_stat(&pair->diff_ss, alpha,
    468 				  pair->a_start, pair->b_start);
    469 		tst_upd_diff_stat(&pair->diff_sa, alpha,
    470 				  pair->a_end, pair->a_start);
    471 		tst_upd_diff_stat(&pair->diff_sb, alpha,
    472 				  pair->b_end, pair->b_start);
    473 		tst_upd_diff_stat(&pair->diff_ab, alpha,
    474 				  pair->a_end, pair->b_end);
    475 		tst_upd_stat(&pair->spins_avg, alpha, pair->spins);
    476 		if (pair->sampling > 0 && --pair->sampling == 0) {
    477 			tst_res(TINFO, "Minimum sampling period ended");
    478 			tst_fzsync_pair_info(pair);
    479 		}
    480 	} else if (fabsf(pair->diff_ab.avg) >= 1 && pair->spins_avg.avg >= 1) {
    481 		per_spin_time = fabsf(pair->diff_ab.avg) / pair->spins_avg.avg;
    482 		time_delay = drand48() * (pair->diff_sa.avg + pair->diff_sb.avg)
    483 			- pair->diff_sb.avg;
    484 		pair->delay += (int)(time_delay / per_spin_time);
    485 
    486 		if (!pair->sampling) {
    487 			tst_res(TINFO,
    488 				"Reached deviation ratios < %.2f, introducing randomness",
    489 				pair->max_dev_ratio);
    490 			tst_res(TINFO, "Delay range is [-%d, %d]",
    491 				(int)(pair->diff_sb.avg / per_spin_time) + pair->delay_bias,
    492 				(int)(pair->diff_sa.avg / per_spin_time) - pair->delay_bias);
    493 			tst_fzsync_pair_info(pair);
    494 			pair->sampling = -1;
    495 		}
    496 	} else if (!pair->sampling) {
    497 		tst_res(TWARN, "Can't calculate random delay");
    498 		pair->sampling = -1;
    499 	}
    500 
    501 	pair->spins = 0;
    502 }
    503 
    504 /**
    505  * Wait for the other thread
    506  *
    507  * @relates tst_fzsync_pair
    508  * @param our_cntr The counter for the thread we are on
    509  * @param other_cntr The counter for the thread we are synchronising with
    510  * @param spins A pointer to the spin counter or NULL
    511  *
    512  * Used by tst_fzsync_pair_wait_a(), tst_fzsync_pair_wait_b(),
    513  * tst_fzsync_start_race_a(), etc. If the calling thread is ahead of the other
    514  * thread, then it will spin wait. Unlike pthread_barrier_wait it will never
    515  * use futex and can count the number of spins spent waiting.
    516  *
    517  * @return A non-zero value if the thread should continue otherwise the
    518  * calling thread should exit.
    519  */
    520 static inline void tst_fzsync_pair_wait(int *our_cntr,
    521 					int *other_cntr,
    522 					int *spins)
    523 {
    524 	if (tst_atomic_inc(other_cntr) == INT_MAX) {
    525 		/*
    526 		 * We are about to break the invariant that the thread with
    527 		 * the lowest count is in front of the other. So we must wait
    528 		 * here to ensure the other thread has at least reached the
    529 		 * line above before doing that. If we are in rear position
    530 		 * then our counter may already have been set to zero.
    531 		 */
    532 		while (tst_atomic_load(our_cntr) > 0
    533 		       && tst_atomic_load(our_cntr) < INT_MAX) {
    534 			if (spins)
    535 				(*spins)++;
    536 		}
    537 
    538 		tst_atomic_store(0, other_cntr);
    539 		/*
    540 		 * Once both counters have been set to zero the invariant
    541 		 * is restored and we can continue.
    542 		 */
    543 		while (tst_atomic_load(our_cntr) > 1)
    544 			;
    545 	} else {
    546 		/*
    547 		 * If our counter is less than the other thread's we are ahead
    548 		 * of it and need to wait.
    549 		 */
    550 		while (tst_atomic_load(our_cntr) < tst_atomic_load(other_cntr)) {
    551 			if (spins)
    552 				(*spins)++;
    553 		}
    554 	}
    555 }
    556 
    557 /**
    558  * Wait in thread A
    559  *
    560  * @relates tst_fzsync_pair
    561  * @sa tst_fzsync_pair_wait
    562  */
    563 static inline void tst_fzsync_wait_a(struct tst_fzsync_pair *pair)
    564 {
    565 	tst_fzsync_pair_wait(&pair->a_cntr, &pair->b_cntr, NULL);
    566 }
    567 
    568 /**
    569  * Wait in thread B
    570  *
    571  * @relates tst_fzsync_pair
    572  * @sa tst_fzsync_pair_wait
    573  */
    574 static inline void tst_fzsync_wait_b(struct tst_fzsync_pair *pair)
    575 {
    576 	tst_fzsync_pair_wait(&pair->b_cntr, &pair->a_cntr, NULL);
    577 }
    578 
    579 /**
    580  * Decide whether to continue running thread A
    581  *
    582  * @relates tst_fzsync_pair
    583  *
    584  * Checks some values and decides whether it is time to break the loop of
    585  * thread A.
    586  *
    587  * @return True to continue and false to break.
    588  * @sa tst_fzsync_run_a
    589  */
    590 static inline int tst_fzsync_run_a(struct tst_fzsync_pair *pair)
    591 {
    592 	int exit = 0;
    593 	float rem_p = 1 - tst_timeout_remaining() / pair->exec_time_start;
    594 
    595 	if ((pair->exec_time_p * SAMPLING_SLICE < rem_p)
    596 		&& (pair->sampling > 0)) {
    597 		tst_res(TINFO, "Stopped sampling at %d (out of %d) samples, "
    598 			"sampling time reached 50%% of the total time limit",
    599 			pair->exec_loop, pair->min_samples);
    600 		pair->sampling = 0;
    601 		tst_fzsync_pair_info(pair);
    602 	}
    603 
    604 	if (pair->exec_time_p < rem_p) {
    605 		tst_res(TINFO,
    606 			"Exceeded execution time, requesting exit");
    607 		exit = 1;
    608 	}
    609 
    610 	if (++pair->exec_loop > pair->exec_loops) {
    611 		tst_res(TINFO,
    612 			"Exceeded execution loops, requesting exit");
    613 		exit = 1;
    614 	}
    615 
    616 	tst_atomic_store(exit, &pair->exit);
    617 	tst_fzsync_wait_a(pair);
    618 
    619 	if (exit) {
    620 		tst_fzsync_pair_cleanup(pair);
    621 		return 0;
    622 	}
    623 
    624 	return 1;
    625 }
    626 
    627 /**
    628  * Decide whether to continue running thread B
    629  *
    630  * @relates tst_fzsync_pair
    631  * @sa tst_fzsync_run_a
    632  */
    633 static inline int tst_fzsync_run_b(struct tst_fzsync_pair *pair)
    634 {
    635 	tst_fzsync_wait_b(pair);
    636 	return !tst_atomic_load(&pair->exit);
    637 }
    638 
    639 /**
    640  * Marks the start of a race region in thread A
    641  *
    642  * @relates tst_fzsync_pair
    643  *
    644  * This should be placed just before performing whatever action can cause a
    645  * race condition. Usually it is placed just before a syscall and
    646  * tst_fzsync_end_race_a() is placed just afterwards.
    647  *
    648  * A corresponding call to tst_fzsync_start_race_b() should be made in thread
    649  * B.
    650  *
    651  * @return A non-zero value if the calling thread should continue to loop. If
    652  * it returns zero then tst_fzsync_exit() has been called and you must exit
    653  * the thread.
    654  *
    655  * @sa tst_fzsync_pair_update
    656  */
    657 static inline void tst_fzsync_start_race_a(struct tst_fzsync_pair *pair)
    658 {
    659 	volatile int delay;
    660 
    661 	tst_fzsync_pair_update(pair);
    662 
    663 	tst_fzsync_wait_a(pair);
    664 
    665 	delay = pair->delay;
    666 	while (delay < 0)
    667 		delay++;
    668 
    669 	tst_fzsync_time(&pair->a_start);
    670 }
    671 
    672 /**
    673  * Marks the end of a race region in thread A
    674  *
    675  * @relates tst_fzsync_pair
    676  * @sa tst_fzsync_start_race_a
    677  */
    678 static inline void tst_fzsync_end_race_a(struct tst_fzsync_pair *pair)
    679 {
    680 	tst_fzsync_time(&pair->a_end);
    681 	tst_fzsync_pair_wait(&pair->a_cntr, &pair->b_cntr, &pair->spins);
    682 }
    683 
    684 /**
    685  * Marks the start of a race region in thread B
    686  *
    687  * @relates tst_fzsync_pair
    688  * @sa tst_fzsync_start_race_a
    689  */
    690 static inline void tst_fzsync_start_race_b(struct tst_fzsync_pair *pair)
    691 {
    692 	volatile int delay;
    693 
    694 	tst_fzsync_wait_b(pair);
    695 
    696 	delay = pair->delay;
    697 	while (delay > 0)
    698 		delay--;
    699 
    700 	tst_fzsync_time(&pair->b_start);
    701 }
    702 
    703 /**
    704  * Marks the end of a race region in thread B
    705  *
    706  * @relates tst_fzsync_pair
    707  * @sa tst_fzsync_start_race_a
    708  */
    709 static inline void tst_fzsync_end_race_b(struct tst_fzsync_pair *pair)
    710 {
    711 	tst_fzsync_time(&pair->b_end);
    712 	tst_fzsync_pair_wait(&pair->b_cntr, &pair->a_cntr, &pair->spins);
    713 }
    714 
    715 /**
    716  * Add some amount to the delay bias
    717  *
    718  * @relates tst_fzsync_pair
    719  * @param change The amount to add, can be negative
    720  *
    721  * A positive change delays thread B and a negative one delays thread
    722  * A.
    723  *
    724  * It is intended to be used in tests where the time taken by syscall A and/or
    725  * B are significantly affected by their chronological order. To the extent
    726  * that the delay range will not include the correct values if too many of the
    727  * initial samples are taken when the syscalls (or operations within the
    728  * syscalls) happen in the wrong order.
    729  *
    730  * An example of this is cve/cve-2016-7117.c where a call to close() is racing
    731  * with a call to recvmmsg(). If close() happens before recvmmsg() has chance
    732  * to check if the file descriptor is open then recvmmsg() completes very
    733  * quickly. If the call to close() happens once recvmmsg() has already checked
    734  * the descriptor it takes much longer. The sample where recvmmsg() completes
    735  * quickly is essentially invalid for our purposes. The test uses the simple
    736  * heuristic of whether recvmmsg() returns EBADF, to decide if it should call
    737  * tst_fzsync_pair_add_bias() to further delay syscall B.
    738  */
    739 static inline void tst_fzsync_pair_add_bias(struct tst_fzsync_pair *pair, int change)
    740 {
    741 	if (pair->sampling > 0)
    742 		pair->delay_bias += change;
    743 }
    744 
    745 #endif /* TST_FUZZY_SYNC_H__ */
    746