Skip to content

Commit

Permalink
MDEV-22544: Inconsistent and Incorrect rw-lock stats
Browse files Browse the repository at this point in the history
- There are multiple inconsistency and incorrect way in which rw-lock
  stats are calculated.

- shared rw-lock stats:
  "rounds" counter is incremented only once for N rounds done
  in spin-cycle.

- all rw-lock stats:
  If the spin-cycle is short-circuited then attempts are re-counted.
  [If spin-cycle is interrupted, before it completes
   srv_n_spin_wait_rounds (default 30) rounds, spin_count is incremented
   to consider this. If thread resumes spin-cycle (due to unavailability
   of the locks) and is again interrupted or completed, spin_count
   is again incremented with the total count, failing to adjust the
   previous attempt increment].

- s/x rw-lock stats:
  spin_loop counter is not incremented at-all instead it is projected
  as 0 (in show engine output) and division to calculate spin-round per
  spin-loop is adjusted.
  As per the original semantics spin_loop counter should be incremented
  once per spin_loop execution.

- sx rw-lock stats:
  sx locks increments spin_loop counter but instead of incrementing it
  once for a spin_loop invocation it does it multiple times based on how
  many time spin_loop flow is repeated for same instance post os-wait.
  • Loading branch information
mysqlonarm committed May 14, 2020
1 parent f827ba3 commit dcb0bd5
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions storage/innobase/sync/sync0rw.cc
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,13 @@ rw_lock_s_lock_spin(

ut_ad(rw_lock_validate(lock));

rw_lock_stats.rw_s_spin_wait_count.inc();

lock_loop:

/* Spin waiting for the writer field to become free */
HMT_low();
ulint j = i;
while (i < srv_n_spin_wait_rounds && lock->lock_word <= 0) {
ut_delay(srv_spin_wait_delay);
i++;
Expand All @@ -307,7 +310,7 @@ rw_lock_s_lock_spin(
os_thread_yield();
}

++spin_count;
spin_count += lint(i - j);

/* We try once again to obtain the lock */
if (rw_lock_s_lock_low(lock, pass, file_name, line)) {
Expand Down Expand Up @@ -428,7 +431,7 @@ rw_lock_x_lock_wait_func(
HMT_medium();

/* If there is still a reader, then go to sleep.*/
++n_spins;
n_spins += i;

sync_cell_t* cell;

Expand Down Expand Up @@ -654,6 +657,12 @@ rw_lock_x_lock_func(
ut_ad(rw_lock_validate(lock));
ut_ad(!rw_lock_own(lock, RW_LOCK_S));

if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
/* Locking succeeded */
return;
}
rw_lock_stats.rw_x_spin_wait_count.inc();

lock_loop:

if (rw_lock_x_lock_low(lock, pass, file_name, line)) {
Expand All @@ -673,6 +682,7 @@ rw_lock_x_lock_func(

/* Spin waiting for the lock_word to become free */
HMT_low();
ulint j = i;
while (i < srv_n_spin_wait_rounds
&& lock->lock_word <= X_LOCK_HALF_DECR) {

Expand All @@ -681,7 +691,7 @@ rw_lock_x_lock_func(
}

HMT_medium();
spin_count += i;
spin_count += lint(i - j);

if (i >= srv_n_spin_wait_rounds) {

Expand Down Expand Up @@ -749,11 +759,17 @@ rw_lock_sx_lock_func(
sync_array_t* sync_arr;
ulint spin_count = 0;
uint64_t count_os_wait = 0;
ulint spin_wait_count = 0;

ut_ad(rw_lock_validate(lock));
ut_ad(!rw_lock_own(lock, RW_LOCK_S));

if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
/* Locking succeeded */
return;
}

rw_lock_stats.rw_sx_spin_wait_count.inc();

lock_loop:

if (rw_lock_sx_lock_low(lock, pass, file_name, line)) {
Expand All @@ -765,24 +781,22 @@ rw_lock_sx_lock_func(
}

rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);

/* Locking succeeded */
return;

} else {

++spin_wait_count;

/* Spin waiting for the lock_word to become free */
ulint j = i;
while (i < srv_n_spin_wait_rounds
&& lock->lock_word <= X_LOCK_HALF_DECR) {

ut_delay(srv_spin_wait_delay);
i++;
}

spin_count += i;
spin_count += lint(i - j);

if (i >= srv_n_spin_wait_rounds) {

Expand Down Expand Up @@ -814,7 +828,6 @@ rw_lock_sx_lock_func(
}

rw_lock_stats.rw_sx_spin_round_count.add(spin_count);
rw_lock_stats.rw_sx_spin_wait_count.add(spin_wait_count);

/* Locking succeeded */
return;
Expand Down

0 comments on commit dcb0bd5

Please sign in to comment.