Commit d96fccc5 authored by Gleb Smirnoff's avatar Gleb Smirnoff
Browse files

epoch: with EPOCH_TRACE add epoch_where_report()

which will report where the epoch was entered and also
mark the tracker, so that exit will also be reported.

Helps to understand epoch entrance/exit scenarios in
complex cases, like network stack.  As everything else
under EPOCH_TRACE it is a developer only tool.
parent 9e93d2b3
......@@ -147,6 +147,13 @@ static struct sx epoch_sx;
#define EPOCH_LOCK() sx_xlock(&epoch_sx)
#define EPOCH_UNLOCK() sx_xunlock(&epoch_sx)
static epoch_record_t
epoch_currecord(epoch_t epoch)
{
return (zpcpu_get(epoch->e_pcpu_record));
}
#ifdef EPOCH_TRACE
struct stackentry {
RB_ENTRY(stackentry) se_node;
......@@ -230,6 +237,7 @@ epoch_trace_enter(struct thread *td, epoch_t epoch, epoch_tracker_t et,
et->et_epoch = epoch;
et->et_file = file;
et->et_line = line;
et->et_flags = 0;
SLIST_INSERT_HEAD(&td->td_epochs, et, et_tlink);
}
......@@ -250,6 +258,9 @@ epoch_trace_exit(struct thread *td, epoch_t epoch, epoch_tracker_t et,
SLIST_REMOVE(&td->td_epochs, et, epoch_tracker, et_tlink);
} else
SLIST_REMOVE_HEAD(&td->td_epochs, et_tlink);
if (et->et_flags & ET_REPORT_EXIT)
printf("Td %p exiting epoch %s at %s:%d\n", td, epoch->e_name,
file, line);
}
/* Used by assertions that check thread state before going to sleep. */
......@@ -262,6 +273,28 @@ epoch_trace_list(struct thread *td)
printf("Epoch %s entered at %s:%d\n", iet->et_epoch->e_name,
iet->et_file, iet->et_line);
}
void
epoch_where_report(epoch_t epoch)
{
epoch_record_t er;
struct epoch_tracker *tdwait;
MPASS(epoch != NULL);
MPASS((epoch->e_flags & EPOCH_PREEMPT) != 0);
MPASS(!THREAD_CAN_SLEEP());
critical_enter();
er = epoch_currecord(epoch);
TAILQ_FOREACH(tdwait, &er->er_tdlist, et_link)
if (tdwait->et_td == curthread)
break;
critical_exit();
if (tdwait != NULL) {
tdwait->et_flags |= ET_REPORT_EXIT;
printf("Td %p entered epoch %s at %s:%d\n", curthread,
epoch->e_name, tdwait->et_file, tdwait->et_line);
}
}
#endif /* EPOCH_TRACE */
static void
......@@ -422,13 +455,6 @@ epoch_free(epoch_t epoch)
EPOCH_UNLOCK();
}
static epoch_record_t
epoch_currecord(epoch_t epoch)
{
return (zpcpu_get(epoch->e_pcpu_record));
}
#define INIT_CHECK(epoch) \
do { \
if (__predict_false((epoch) == NULL)) \
......
......@@ -61,6 +61,8 @@ struct epoch_tracker {
SLIST_ENTRY(epoch_tracker) et_tlink;
const char *et_file;
int et_line;
int et_flags;
#define ET_REPORT_EXIT 0x1
#endif
} __aligned(sizeof(void *));
typedef struct epoch_tracker *epoch_tracker_t;
......@@ -86,6 +88,7 @@ void _epoch_enter_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE);
void _epoch_exit_preempt(epoch_t epoch, epoch_tracker_t et EPOCH_FILE_LINE);
#ifdef EPOCH_TRACE
void epoch_trace_list(struct thread *);
void epoch_where_report(epoch_t);
#define epoch_enter_preempt(epoch, et) _epoch_enter_preempt(epoch, et, __FILE__, __LINE__)
#define epoch_exit_preempt(epoch, et) _epoch_exit_preempt(epoch, et, __FILE__, __LINE__)
#else
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment