Page MenuHomeFreeBSD

D55640.diff
No OneTemporary

D55640.diff

diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c
--- a/sys/kern/subr_trap.c
+++ b/sys/kern/subr_trap.c
@@ -74,10 +74,6 @@
#include <sys/epoch.h>
#endif
-volatile uint32_t __read_frequently hpts_that_need_softclock = 0;
-
-void (*tcp_hpts_softclock)(void);
-
/*
* Define the code needed before returning to user mode, for trap and
* syscall.
@@ -129,18 +125,6 @@
if (PMC_THREAD_HAS_SAMPLES(td))
PMC_CALL_HOOK(td, PMC_FN_THR_USERRET, NULL);
#endif
- /*
- * Calling tcp_hpts_softclock() here allows us to avoid frequent,
- * expensive callouts that trash the cache and lead to a much higher
- * number of interrupts and context switches. Testing on busy web
- * servers at Netflix has shown that this improves CPU use by 7% over
- * relying only on callouts to drive HPTS, and also results in idle
- * power savings on mostly idle servers.
- * This was inspired by the paper "Soft Timers: Efficient Microsecond
- * Software Timer Support for Network Processing"
- * by Mohit Aron and Peter Druschel.
- */
- tcp_hpts_softclock();
/*
* Let the scheduler adjust our priority etc.
*/
diff --git a/sys/netinet/tcp_hpts.h b/sys/netinet/tcp_hpts.h
--- a/sys/netinet/tcp_hpts.h
+++ b/sys/netinet/tcp_hpts.h
@@ -93,6 +93,9 @@
#ifdef _KERNEL
+void _tcp_hpts_softclock(void);
+extern void (*tcp_hpts_softclock)(void);
+
extern struct tcp_hptsi *tcp_hptsi_pace;
/*
diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c
--- a/sys/netinet/tcp_hpts.c
+++ b/sys/netinet/tcp_hpts.c
@@ -185,6 +185,7 @@
static MALLOC_DEFINE(M_TCPHPTS, "tcp_hpts", "TCP hpts");
static void tcp_hpts_thread(void *ctx);
+static volatile uint32_t __read_frequently hpts_that_need_softclock;
#define LOWEST_SLEEP_ALLOWED 50
#define DEFAULT_MIN_SLEEP 250 /* How many usec's is default for hpts sleep
@@ -1560,13 +1561,16 @@
return(pace->rp_ent[(curcpu % pace->rp_num_hptss)]);
}
-static void
-__tcp_run_hpts(void)
+void
+_tcp_hpts_softclock(void)
{
struct epoch_tracker et;
struct tcp_hpts_entry *hpts;
int slots_ran;
+ if (hpts_that_need_softclock == 0)
+ return;
+
hpts = tcp_choose_hpts_to_run(tcp_hptsi_pace);
if (hpts->p_hpts_active) {
@@ -1607,7 +1611,7 @@
}
/*
* In this mode the timer is a backstop to
- * all the userret/lro_flushes so we use
+ * all the lro_flushes so we use
* the dynamic value and set the on_min_sleep
* flag so we will not be awoken.
*/
@@ -1733,7 +1737,7 @@
}
/*
* In this mode the timer is a backstop to
- * all the userret/lro_flushes so we use
+ * all the lro_flushes so we use
* the dynamic value and set the on_min_sleep
* flag so we will not be awoken.
*/
@@ -2124,9 +2128,6 @@
/* Start the threads */
tcp_hptsi_start(tcp_hptsi_pace);
- /* Enable the global HPTS softclock function */
- tcp_hpts_softclock = __tcp_run_hpts;
-
/* Initialize LRO HPTS */
tcp_lro_hpts_init();
@@ -2154,9 +2155,6 @@
{
tcp_lro_hpts_uninit();
- /* Disable the global HPTS softclock function */
- atomic_store_ptr(&tcp_hpts_softclock, NULL);
-
tcp_hptsi_stop(tcp_hptsi_pace);
tcp_hptsi_destroy(tcp_hptsi_pace);
tcp_hptsi_pace = NULL;
@@ -2185,8 +2183,7 @@
/*
* Since we are a dependency of TCP stack modules, they should
* already be unloaded, and the HPTS ring is empty. However,
- * function pointer manipulations aren't 100% safe. Although,
- * tcp_hpts_mod_unload() use atomic(9) the userret() doesn't.
+ * function pointer manipulations aren't 100% safe.
* Thus, allow only forced unload of HPTS.
*/
return (EBUSY);
diff --git a/sys/netinet/tcp_lro.c b/sys/netinet/tcp_lro.c
--- a/sys/netinet/tcp_lro.c
+++ b/sys/netinet/tcp_lro.c
@@ -89,6 +89,7 @@
long tcplro_stacks_wanting_mbufq;
int (*tcp_lro_flush_tcphpts)(struct lro_ctrl *lc, struct lro_entry *le);
+void (*tcp_hpts_softclock)(void);
counter_u64_t tcp_inp_lro_direct_queue;
counter_u64_t tcp_inp_lro_wokeup_queue;
@@ -1257,7 +1258,8 @@
done:
/* flush active streams */
tcp_lro_rx_done(lc);
- tcp_hpts_softclock();
+ if (tcp_hpts_softclock != NULL)
+ tcp_hpts_softclock();
lc->lro_mbuf_count = 0;
}
diff --git a/sys/netinet/tcp_lro_hpts.c b/sys/netinet/tcp_lro_hpts.c
--- a/sys/netinet/tcp_lro_hpts.c
+++ b/sys/netinet/tcp_lro_hpts.c
@@ -665,11 +665,13 @@
void
tcp_lro_hpts_init(void)
{
+ tcp_hpts_softclock = _tcp_hpts_softclock;
tcp_lro_flush_tcphpts = _tcp_lro_flush_tcphpts;
}
void
tcp_lro_hpts_uninit(void)
{
- atomic_store_ptr(&tcp_lro_flush_tcphpts, NULL);
+ tcp_hpts_softclock = NULL;
+ tcp_lro_flush_tcphpts = NULL;
}
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -399,14 +399,6 @@
extern int cpu_disable_c2_sleep;
extern int cpu_disable_c3_sleep;
-extern void (*tcp_hpts_softclock)(void);
-extern volatile uint32_t __read_frequently hpts_that_need_softclock;
-
-#define tcp_hpts_softclock() do { \
- if (hpts_that_need_softclock > 0) \
- tcp_hpts_softclock(); \
-} while (0)
-
char *kern_getenv(const char *name);
void freeenv(char *env);
int getenv_int(const char *name, int *data);

File Metadata

Mime Type
text/plain
Expires
Wed, Jun 24, 12:07 PM (6 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34282695
Default Alt Text
D55640.diff (5 KB)

Event Timeline