Skip to content

Commit d00fe7a

Browse files
committed
common: optimize assert_data_ctx passing in ceph_assert()
\### After ``` 0000000000e58600 <PeeringState::clear_blocked_outgoing()>: e58600: 48 83 ec 18 sub $0x18,%rsp e58604: 48 83 bf e0 00 00 00 cmpq $0x0,0xe0(%rdi) e5860b: 00 e5860c: 0f 84 fc 0f b0 ff je 95960e <PeeringState::clear_blocked_outgoing() [clone .cold]+0x14> e58612: 80 bf 40 01 00 00 00 cmpb $0x0,0x140(%rdi) e58619: 0f 84 db 0f b0 ff je 9595fa <PeeringState::clear_blocked_outgoing() [clone .cold]> e5861f: 80 bf 18 01 00 00 00 cmpb $0x0,0x118(%rdi) e58626: 75 08 jne e58630 <PeeringState::clear_blocked_outgoing()+0x30> e58628: 48 83 c4 18 add $0x18,%rsp e5862c: c3 retq e5862d: 0f 1f 00 nopl (%rax) e58630: c6 87 18 01 00 00 00 movb $0x0,0x118(%rdi) e58637: 48 8b bf f8 00 00 00 mov 0xf8(%rdi),%rdi e5863e: 48 83 c4 18 add $0x18,%rsp e58642: e9 89 bc ff ff jmpq e542d0 <std::_Rb_tree<int, std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > >, std::_Select1st<std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > > >, std::less<int>, std::allocator<std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > > > >::_M_erase(std::_Rb_tree_node<std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > > >*) [clone .isra.0]> e58647: 90 nop e58648: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) e5864f: 00 ``` \### Vanilla main Loading of `assert_data_ctx` was `unlikely` bot not `cold`: ``` 0000000000e3cf90 <PeeringState::clear_blocked_outgoing()>: e3cf90: 48 83 ec 08 sub $0x8,%rsp e3cf94: 48 83 bf e0 00 00 00 cmpq $0x0,0xe0(%rdi) e3cf9b: 00 e3cf9c: 74 3d je e3cfdb <PeeringState::clear_blocked_outgoing()+0x4b> e3cf9e: 80 bf 40 01 00 00 00 cmpb $0x0,0x140(%rdi) e3cfa5: 74 28 je e3cfcf <PeeringState::clear_blocked_outgoing()+0x3f> e3cfa7: 80 bf 18 01 00 00 00 cmpb $0x0,0x118(%rdi) e3cfae: 75 08 jne e3cfb8 <PeeringState::clear_blocked_outgoing()+0x28> e3cfb0: 48 83 c4 08 add $0x8,%rsp e3cfb4: c3 retq e3cfb5: 0f 1f 00 nopl (%rax) e3cfb8: c6 87 18 01 00 00 00 movb $0x0,0x118(%rdi) e3cfbf: 48 8b bf f8 00 00 00 mov 0xf8(%rdi),%rdi e3cfc6: 48 83 c4 08 add $0x8,%rsp e3cfca: e9 01 bd ff ff jmpq e38cd0 <std::_Rb_tree<int, std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > >, std::_Select1st<std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > > >, std::less<int>, std::allocator<std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > > > >::_M_erase(std::_Rb_tree_node<std::pair<int const, std::vector<boost::intrusive_ptr<Message>, std::allocator<boost::intrusive_ptr<Message> > > > >*) [clone .isra.0]> e3cfcf: 48 8d 3d aa 0b 29 01 lea 0x1290baa(%rip),%rdi # 20cdb80 <PeeringState::clear_blocked_outgoing()::assert_data_ctx> e3cfd6: e8 64 6c b6 ff callq 9a3c3f <ceph::__ceph_assert_fail(ceph::assert_data const&)> e3cfdb: 48 8d 3d be 0b 29 01 lea 0x1290bbe(%rip),%rdi # 20cdba0 <PeeringState::clear_blocked_outgoing()::assert_data_ctx> e3cfe2: e8 58 6c b6 ff callq 9a3c3f <ceph::__ceph_assert_fail(ceph::assert_data const&)> e3cfe7: 90 nop e3cfe8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) e3cfef: 00 ``` Fixes: https://tracker.ceph.com/issues/70476 Signed-off-by: Radoslaw Zarzynski <[email protected]>
1 parent bfa83df commit d00fe7a

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

src/include/ceph_assert.h

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ struct assert_data {
5252

5353
extern void __ceph_assert_fail(const char *assertion, const char *file, int line, const char *function);
5454
extern void __ceph_assert_fail(const assert_data &ctx);
55+
template <const assert_data* AssertCtxV>
56+
[[gnu::noinline, gnu::cold]] static void __ceph_assert_fail() {
57+
__ceph_assert_fail(*AssertCtxV);
58+
}
5559

5660
extern void __ceph_assertf_fail(const char *assertion, const char *file, int line, const char *function, const char* msg, ...);
5761
extern void __ceph_assert_warn(const char *assertion, const char *file, int line, const char *function);
@@ -98,11 +102,14 @@ using namespace ceph;
98102
} while (false)
99103
#else
100104
#define ceph_assert(expr) \
101-
do { static const ceph::assert_data assert_data_ctx = \
102-
{__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION}; \
103-
((expr) \
104-
? _CEPH_ASSERT_VOID_CAST (0) \
105-
: ::ceph::__ceph_assert_fail(assert_data_ctx)); } while(false)
105+
do { \
106+
static const auto func_name = __CEPH_ASSERT_FUNCTION; \
107+
[] (const bool eval) { \
108+
static const ceph::assert_data assert_data_ctx = \
109+
{__STRING(expr), __FILE__, __LINE__, func_name}; \
110+
((eval) \
111+
? _CEPH_ASSERT_VOID_CAST (0) \
112+
: ::ceph::__ceph_assert_fail<&assert_data_ctx>()); }((bool)(expr)); } while(false)
106113
#endif
107114

108115
// this variant will *never* get compiled out to NDEBUG in the future.
@@ -116,11 +123,14 @@ using namespace ceph;
116123
} while(false)
117124
#else
118125
#define ceph_assert_always(expr) \
119-
do { static const ceph::assert_data assert_data_ctx = \
120-
{__STRING(expr), __FILE__, __LINE__, __CEPH_ASSERT_FUNCTION}; \
121-
((expr) \
122-
? _CEPH_ASSERT_VOID_CAST (0) \
123-
: ::ceph::__ceph_assert_fail(assert_data_ctx)); } while(false)
126+
do { \
127+
static const auto func_name = __CEPH_ASSERT_FUNCTION; \
128+
[] (const bool eval) { \
129+
static const ceph::assert_data assert_data_ctx = \
130+
{__STRING(expr), __FILE__, __LINE__, func_name}; \
131+
((eval) \
132+
? _CEPH_ASSERT_VOID_CAST (0) \
133+
: ::ceph::__ceph_assert_fail<&assert_data_ctx>()); }((bool)(expr)); } while(false)
124134
#endif
125135

126136
// Named by analogy with printf. Along with an expression, takes a format

0 commit comments

Comments
 (0)