rcutorture.c (61670adcb4a9f66ff3fa8a9e846a623d9a9e1553) | rcutorture.c (e0aff97355575ac6a28a48a4217533a3953095c5) |
---|---|
1/* 2 * Read-Copy Update module-based torture test facility 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 42 unchanged lines hidden (view full) --- 51#include <linux/srcu.h> 52#include <linux/slab.h> 53#include <linux/trace_clock.h> 54#include <asm/byteorder.h> 55#include <linux/torture.h> 56#include <linux/vmalloc.h> 57#include <linux/sched/debug.h> 58#include <linux/sched/sysctl.h> | 1/* 2 * Read-Copy Update module-based torture test facility 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * --- 42 unchanged lines hidden (view full) --- 51#include <linux/srcu.h> 52#include <linux/slab.h> 53#include <linux/trace_clock.h> 54#include <asm/byteorder.h> 55#include <linux/torture.h> 56#include <linux/vmalloc.h> 57#include <linux/sched/debug.h> 58#include <linux/sched/sysctl.h> |
59#include <linux/oom.h> |
|
59 60#include "rcu.h" 61 62MODULE_LICENSE("GPL"); 63MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@joshtriplett.org>"); 64 65 66/* Bits for ->extendables field, extendables param, and related definitions. */ --- 1552 unchanged lines hidden (view full) --- 1619 struct rcu_fwd_cb *rfc_next; 1620 int rfc_gps; 1621}; 1622static DEFINE_SPINLOCK(rcu_fwd_lock); 1623static struct rcu_fwd_cb *rcu_fwd_cb_head; 1624static struct rcu_fwd_cb **rcu_fwd_cb_tail = &rcu_fwd_cb_head; 1625static long n_launders_cb; 1626static unsigned long rcu_fwd_startat; | 60 61#include "rcu.h" 62 63MODULE_LICENSE("GPL"); 64MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and Josh Triplett <josh@joshtriplett.org>"); 65 66 67/* Bits for ->extendables field, extendables param, and related definitions. */ --- 1552 unchanged lines hidden (view full) --- 1620 struct rcu_fwd_cb *rfc_next; 1621 int rfc_gps; 1622}; 1623static DEFINE_SPINLOCK(rcu_fwd_lock); 1624static struct rcu_fwd_cb *rcu_fwd_cb_head; 1625static struct rcu_fwd_cb **rcu_fwd_cb_tail = &rcu_fwd_cb_head; 1626static long n_launders_cb; 1627static unsigned long rcu_fwd_startat; |
1628static bool rcu_fwd_emergency_stop; |
|
1627#define MAX_FWD_CB_JIFFIES (8 * HZ) /* Maximum CB test duration. */ 1628#define MIN_FWD_CB_LAUNDERS 3 /* This many CB invocations to count. */ 1629#define MIN_FWD_CBS_LAUNDERED 100 /* Number of counted CBs. */ 1630static long n_launders_hist[2 * MAX_FWD_CB_JIFFIES / HZ]; 1631 1632/* Callback function for continuous-flood RCU callbacks. */ 1633static void rcu_torture_fwd_cb_cr(struct rcu_head *rhp) 1634{ --- 41 unchanged lines hidden (view full) --- 1676 } 1677 cver = READ_ONCE(rcu_torture_current_version); 1678 gps = cur_ops->get_gp_seq(); 1679 sd = cur_ops->stall_dur() + 1; 1680 sd4 = (sd + fwd_progress_div - 1) / fwd_progress_div; 1681 dur = sd4 + torture_random(&trs) % (sd - sd4); 1682 WRITE_ONCE(rcu_fwd_startat, jiffies); 1683 stopat = rcu_fwd_startat + dur; | 1629#define MAX_FWD_CB_JIFFIES (8 * HZ) /* Maximum CB test duration. */ 1630#define MIN_FWD_CB_LAUNDERS 3 /* This many CB invocations to count. */ 1631#define MIN_FWD_CBS_LAUNDERED 100 /* Number of counted CBs. */ 1632static long n_launders_hist[2 * MAX_FWD_CB_JIFFIES / HZ]; 1633 1634/* Callback function for continuous-flood RCU callbacks. */ 1635static void rcu_torture_fwd_cb_cr(struct rcu_head *rhp) 1636{ --- 41 unchanged lines hidden (view full) --- 1678 } 1679 cver = READ_ONCE(rcu_torture_current_version); 1680 gps = cur_ops->get_gp_seq(); 1681 sd = cur_ops->stall_dur() + 1; 1682 sd4 = (sd + fwd_progress_div - 1) / fwd_progress_div; 1683 dur = sd4 + torture_random(&trs) % (sd - sd4); 1684 WRITE_ONCE(rcu_fwd_startat, jiffies); 1685 stopat = rcu_fwd_startat + dur; |
1684 while (time_before(jiffies, stopat) && !torture_must_stop()) { | 1686 while (time_before(jiffies, stopat) && 1687 !READ_ONCE(rcu_fwd_emergency_stop) && !torture_must_stop()) { |
1685 idx = cur_ops->readlock(); 1686 udelay(10); 1687 cur_ops->readunlock(idx); 1688 if (!fwd_progress_need_resched || need_resched()) 1689 cond_resched(); 1690 } 1691 (*tested_tries)++; | 1688 idx = cur_ops->readlock(); 1689 udelay(10); 1690 cur_ops->readunlock(idx); 1691 if (!fwd_progress_need_resched || need_resched()) 1692 cond_resched(); 1693 } 1694 (*tested_tries)++; |
1692 if (!time_before(jiffies, stopat) && !torture_must_stop()) { | 1695 if (!time_before(jiffies, stopat) && 1696 !READ_ONCE(rcu_fwd_emergency_stop) && !torture_must_stop()) { |
1693 (*tested)++; 1694 cver = READ_ONCE(rcu_torture_current_version) - cver; 1695 gps = rcutorture_seq_diff(cur_ops->get_gp_seq(), gps); 1696 WARN_ON(!cver && gps < 2); 1697 pr_alert("%s: Duration %ld cver %ld gps %ld\n", __func__, dur, cver, gps); 1698 } 1699 if (selfpropcb) { 1700 WRITE_ONCE(fcs.stop, 1); --- 33 unchanged lines hidden (view full) --- 1734 n_launders_cb = 0; 1735 n_launders_sa = 0; 1736 n_max_cbs = 0; 1737 n_max_gps = 0; 1738 for (i = 0; i < ARRAY_SIZE(n_launders_hist); i++) 1739 n_launders_hist[i] = 0; 1740 cver = READ_ONCE(rcu_torture_current_version); 1741 gps = cur_ops->get_gp_seq(); | 1697 (*tested)++; 1698 cver = READ_ONCE(rcu_torture_current_version) - cver; 1699 gps = rcutorture_seq_diff(cur_ops->get_gp_seq(), gps); 1700 WARN_ON(!cver && gps < 2); 1701 pr_alert("%s: Duration %ld cver %ld gps %ld\n", __func__, dur, cver, gps); 1702 } 1703 if (selfpropcb) { 1704 WRITE_ONCE(fcs.stop, 1); --- 33 unchanged lines hidden (view full) --- 1738 n_launders_cb = 0; 1739 n_launders_sa = 0; 1740 n_max_cbs = 0; 1741 n_max_gps = 0; 1742 for (i = 0; i < ARRAY_SIZE(n_launders_hist); i++) 1743 n_launders_hist[i] = 0; 1744 cver = READ_ONCE(rcu_torture_current_version); 1745 gps = cur_ops->get_gp_seq(); |
1742 while (time_before(jiffies, stopat) && !torture_must_stop()) { | 1746 while (time_before(jiffies, stopat) && 1747 !READ_ONCE(rcu_fwd_emergency_stop) && !torture_must_stop()) { |
1743 rfcp = READ_ONCE(rcu_fwd_cb_head); 1744 rfcpn = NULL; 1745 if (rfcp) 1746 rfcpn = READ_ONCE(rfcp->rfc_next); 1747 if (rfcpn) { 1748 if (rfcp->rfc_gps >= MIN_FWD_CB_LAUNDERS && 1749 ++n_max_gps >= MIN_FWD_CBS_LAUNDERED) 1750 break; --- 40 unchanged lines hidden (view full) --- 1791 break; 1792 pr_alert("Callback-invocation histogram:"); 1793 for (j = 0; j <= i; j++) 1794 pr_cont(" %ds: %ld", j + 1, n_launders_hist[j]); 1795 pr_cont("\n"); 1796 } 1797} 1798 | 1748 rfcp = READ_ONCE(rcu_fwd_cb_head); 1749 rfcpn = NULL; 1750 if (rfcp) 1751 rfcpn = READ_ONCE(rfcp->rfc_next); 1752 if (rfcpn) { 1753 if (rfcp->rfc_gps >= MIN_FWD_CB_LAUNDERS && 1754 ++n_max_gps >= MIN_FWD_CBS_LAUNDERED) 1755 break; --- 40 unchanged lines hidden (view full) --- 1796 break; 1797 pr_alert("Callback-invocation histogram:"); 1798 for (j = 0; j <= i; j++) 1799 pr_cont(" %ds: %ld", j + 1, n_launders_hist[j]); 1800 pr_cont("\n"); 1801 } 1802} 1803 |
1804 1805/* 1806 * OOM notifier, but this only prints diagnostic information for the 1807 * current forward-progress test. 1808 */ 1809static int rcutorture_oom_notify(struct notifier_block *self, 1810 unsigned long notused, void *nfreed) 1811{ 1812 rcu_fwd_progress_check(1 + (jiffies - READ_ONCE(rcu_fwd_startat) / 2)); 1813 WRITE_ONCE(rcu_fwd_emergency_stop, true); 1814 return NOTIFY_OK; 1815} 1816 1817static struct notifier_block rcutorture_oom_nb = { 1818 .notifier_call = rcutorture_oom_notify 1819}; 1820 |
|
1799/* Carry out grace-period forward-progress testing. */ 1800static int rcu_torture_fwd_prog(void *args) 1801{ 1802 int tested = 0; 1803 int tested_tries = 0; 1804 1805 VERBOSE_TOROUT_STRING("rcu_torture_fwd_progress task started"); 1806 rcu_bind_current_to_nocb(); 1807 if (!IS_ENABLED(CONFIG_SMP) || !IS_ENABLED(CONFIG_RCU_BOOST)) 1808 set_user_nice(current, MAX_NICE); 1809 do { 1810 schedule_timeout_interruptible(fwd_progress_holdoff * HZ); | 1821/* Carry out grace-period forward-progress testing. */ 1822static int rcu_torture_fwd_prog(void *args) 1823{ 1824 int tested = 0; 1825 int tested_tries = 0; 1826 1827 VERBOSE_TOROUT_STRING("rcu_torture_fwd_progress task started"); 1828 rcu_bind_current_to_nocb(); 1829 if (!IS_ENABLED(CONFIG_SMP) || !IS_ENABLED(CONFIG_RCU_BOOST)) 1830 set_user_nice(current, MAX_NICE); 1831 do { 1832 schedule_timeout_interruptible(fwd_progress_holdoff * HZ); |
1833 WRITE_ONCE(rcu_fwd_emergency_stop, false); 1834 register_oom_notifier(&rcutorture_oom_nb); |
|
1811 rcu_torture_fwd_prog_nr(&tested, &tested_tries); 1812 rcu_torture_fwd_prog_cr(); | 1835 rcu_torture_fwd_prog_nr(&tested, &tested_tries); 1836 rcu_torture_fwd_prog_cr(); |
1837 unregister_oom_notifier(&rcutorture_oom_nb); |
|
1813 1814 /* Avoid slow periods, better to test when busy. */ 1815 stutter_wait("rcu_torture_fwd_prog"); 1816 } while (!torture_must_stop()); 1817 /* Short runs might not contain a valid forward-progress attempt. */ 1818 WARN_ON(!tested && tested_tries >= 5); 1819 pr_alert("%s: tested %d tested_tries %d\n", __func__, tested, tested_tries); 1820 torture_kthread_stopping("rcu_torture_fwd_prog"); --- 521 unchanged lines hidden --- | 1838 1839 /* Avoid slow periods, better to test when busy. */ 1840 stutter_wait("rcu_torture_fwd_prog"); 1841 } while (!torture_must_stop()); 1842 /* Short runs might not contain a valid forward-progress attempt. */ 1843 WARN_ON(!tested && tested_tries >= 5); 1844 pr_alert("%s: tested %d tested_tries %d\n", __func__, tested, tested_tries); 1845 torture_kthread_stopping("rcu_torture_fwd_prog"); --- 521 unchanged lines hidden --- |