From: caifeng.zhu@uniswdc.com
To: Ilya Dryomov <idryomov@gmail.com>
Cc: caifeng.zhu@uniswdc.com, Ceph Development <ceph-devel@vger.kernel.org>
Subject: Re: proposal for fine-grain dout control
Date: Mon, 21 Nov 2016 11:17:35 +0800 [thread overview]
Message-ID: <20161121031734.GA33595@T530I> (raw)
In-Reply-To: <CAOi1vP94GDwABdfphqWDc2nZ4pp3GFZVXUnhNFgMuc21fpUknA@mail.gmail.com>
On Fri, Nov 18, 2016 at 03:04:38PM +0100, Ilya Dryomov wrote:
> On Thu, Nov 17, 2016 at 5:32 AM, <caifeng.zhu@uniswdc.com> wrote:
> > Currently dout control is based on module and trace level.
> > In practice, we find that it is much easier to control dout
> > by specifying module, file, function and line, as done by
> > kernel rbd/cephfs client module. The paragraphs below try to
> > propose a way to implement similar control at the ceph server
> > side.
> >
> > As the kernel clients, we can define control points (called
> > doutpoints later) for dout in the macro dout_impl and collect
> > them into a seperate ELF section, like below:
> >
> > #define dout_impl(cct, sub, v) \
> > do { \
> > - if (cct->_conf->subsys.should_gather(sub, v)) { \
> > + static doutpoint_t *_dop; \
> > + DOUTPOINT(TOSTR(sub), __FILE__, __func__, __LINE__); \
> > + \
> > + if (cct->_conf->subsys.should_gather(sub, v) || \
> > + doutpoint_active(_dop)) { \
> >
> > In the above code, DOUTPOINT will define a doutpoint and ask linker
> > to collect it into an ELF section, such as "set_doutpoint". Instead of
> > adding __attribute__((section("set_doutpoint"))) to variables, we resort
> > to inline ASM like below:
> >
> > +typedef struct doutpoint {
> > + const char * dop_module; // module
> > + const char * dop_file; // file name
> > + const char * dop_func; // function name
> > + int dop_line; // line no
> > + volatile int dop_state; // state 0:off, 1:on
> > +} doutpoint_t;
> >
> > +#define TOSTR(a) #a
> > +#define DOUTPOINT(module, file, func, line) \
> > +do { \
> > + __asm__(".pushsection set_doutpoint, \"aw\", @progbits" "\n" \
> > + ".align 32" "\n" \
> > + "416:" "\n" \
> > + ".quad %c1" "\n" \
> > + ".quad %c2" "\n" \
> > + ".quad %c3" "\n" \
> > + ".long %c4" "\n" \
> > + ".long 0" "\n" \
> > + ".popsection" "\n" \
> > + "leaq 416b(%%rip), %0" "\n" \
> > + : "=r"(_dop) \
> > + : "i"(module), "i"(file), "i"(func), "i"(line)); \
> > +} while(0)
> >
> > The reason for inline ASM is that: in C++, there are inline and template
> > functions. static variables defined in these functions will be automatically
> > added attributes by the compiler. thus it impossible to collect all doutpoints
> > into one section.
> >
> > There is another problem to consider: collect doutpoints of shared libs into
> > the main executable. We solve the problem by defining a constructor function
> > and a weak function. The contructor function will automatically register doupoints
> > of shared libs into the main executable. The weak function is to be overriden by
> > the main executable, providing where to register doutponits.
> >
> > //
> > // in common/dout.h
> > //
> > +typedef struct doutsection {
> > + doutpoint_t * start;
> > + doutpoint_t * stop;
> > +} doutsection_t;
> >
> > //
> > // in common/dout.cc
> > //
> > +extern doutpoint_t __start_set_doutpoint[]
> > + __attribute__((weak, visibility("hidden")));
> > +extern doutpoint_t __stop_set_doutpoint[]
> > + __attribute__((weak, visibility("hidden")));
> > +
> > +extern void doutsection_global(doutsection_t **s, int *n)
> > + __attribute__((weak));
> > +
> > +
> > +static void
> > +doutsection_array(doutsection_t **s, int *n)
> > +{
> > + static doutsection_t _sections[10];
> > +
> > + /*
> > + * If doutsection_global is defined, provide
> > + * from the global one; otherwise, fall back
> > + * to local ones.
> > + */
> > + if (doutsection_global)
> > + doutsection_global(s, n);
> > + else {
> > + *s = _sections;
> > + *n = 10;
> > + }
> > +}
> > +
> > +/*
> > + * The 'contructor' attribute means the function will be
> > + * called after dynamic linking for the library or before
> > + * entering into main for the executable.
> > + */
> > +void __attribute__((constructor))
> > +doutpoint_register(void)
> > +{
> > + int i, n;
> > + doutsection_t *s;
> > +
> > + doutsection_array(&s, &n);
> > + for (i = 0; i < n; i++, s++) {
> > + if (!s->start) {
> > + s->start = __start_set_doutpoint;
> > + s->stop = __stop_set_doutpoint;
> > + return;
> > + }
> > + }
> > +}
> >
> > //
> > // in global/global_init.cc
> > //
> > void
> > doutsection_global(doutsection_t **s, int *n)
> > {
> > static doutsection_t _sections[10];
> >
> > *s = _sections;
> > *n = 10;
> > }
> >
> > There are some shortcomings of the proposal: mainly archtecture
> > dependency and compiler dependency. DOUTPOINT exploits one x86
> > instruction; weak symbol support may be different on different
> > compilers.
> >
> > Glad and eager to hear your opinions!
> > If it is useful, I'll post the whole patch.
>
> As someone who has experience with kernel dynamic_debug mechanism,
> I wish we had a subsystem/level mechanism in the kernel client instead.
> While sometimes handy, enabling only a few selected douts doesn't come
> useful that often - more frequently the dout you really need isn't
> there and you end up fiddling with "perf probe" and others, longing for
> a good scriptable dynamic tracer.
>
> It looks like you are proposing this as an addition to the existing
> module/level scheme and not as a replacement though, so it's just an
> observation...
Yes, the proposal is an improvement, rather than a replacement.
When analyzing a problem, we usually started with gross-grained info. After
some analysis and study, we can pinpoint the problem. At that time,we need
fine-grained info. For the current dout, when pinpointing a problem, usually
I'm flooded with too much info. By fine-grained dout control, it is much
easier to get what I really want.
>
> Thanks,
>
> Ilya
> --
> To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2016-11-21 3:20 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-17 4:32 proposal for fine-grain dout control caifeng.zhu
2016-11-18 14:04 ` Ilya Dryomov
2016-11-21 3:17 ` caifeng.zhu [this message]
2016-11-18 14:14 ` John Spray
2016-11-21 2:55 ` caifeng.zhu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161121031734.GA33595@T530I \
--to=caifeng.zhu@uniswdc.com \
--cc=ceph-devel@vger.kernel.org \
--cc=idryomov@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox