Bug 51648 - Xlib makes redundant read(2) calls (through xcb) on xorg sockets
Summary: Xlib makes redundant read(2) calls (through xcb) on xorg sockets
Status: RESOLVED DUPLICATE of bug 29561
Alias: None
Product: xorg
Classification: Unclassified
Component: Lib/Xlib (show other bugs)
Version: unspecified
Hardware: x86-64 (AMD64) FreeBSD
: medium normal
Assignee: Xorg Project Team
QA Contact: Xorg Project Team
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-07-02 02:38 UTC by Yuri
Modified: 2012-07-05 12:29 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Yuri 2012-07-02 02:38:14 UTC
When I ran DTrace script showing all syscall failures, I noticed that FreeBSD 9.0 system is flooded with the failed read(2) requests reading from xorg socket:
Resource temporarily unavailable
read failures mostly come from kdeinit4 process but also from kwin, chrome and even Xorg itself. Rate of failure is ~2500/sec system wide.

Code analysis shows that requests originate from _xcb_in_read function from this line:
int n = read(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len);

I replaced this line with poll(2):
//int n = read(c->fd, c->in.queue + c->in.queue_len, sizeof(c->in.queue) - c->in.queue_len);
    struct pollfd fds = {c->fd, POLLIN|POLLERR|POLLHUP, INFTIM};
    int n = poll(&fds, 1, INFTIM);

This causes the test qt4 app to hang because _xcb_in_read is sometimes called when no actual data is expected from the xorg socket. Particularly, _xcb_in_read is called from XFlush when no data is expected.

I am trying to understand the status of this code and this issue.
For example, is this a generic Xorg issue, does it, for example, exist in Linux too, or it's FreeBSD only? It would look very amazing if Linux also has such issue.

This is abnormal that Xorg code causes so many system call failures, at least because this shortens the battery life and drains other resources.

libxcb-1.7
Comment 1 Uli Schlachter 2012-07-02 03:48:26 UTC
There are just two callers of _xcb_in_read(). _xcb_conn_wait() first does the needed poll(), so shouldn't cause any EAGAINs. Other caller is poll_for_next_event() when called via xcb_poll_for_event(). So in this case, the caller of xcb_poll_for_event() asked us to check if any new events are ready, so checking via read() is the right thing to do. The EAGAIN that we get back is read()'s way of saying "nope, no new event".

So if you see lots of EAGAINs from _xcb_in_read(), something (Xlib?) is doing lots of xcb_poll_for_event() calls.

What effect would adding a call to poll() here have? That's just an extra syscall and thus can only slow down things.

On your question: Yes, since this is expected behavior, I bet this happens on Linux, too. However, why do you call this an issue? What's wrong with this?
Also, since when do syscall failures shorten the batter life "and drain[s] other resources"?

(I won't comment on your patch adding a poll()-call :-) )
Comment 2 Yuri 2012-07-02 16:08:37 UTC
> (I won't comment on your patch adding a poll()-call :-) )

Where did I say this was a suggested patch? This was an experiment, I am not an xorg developer so I experiment with the code to see what is going on.

When I put a breakpoint into _xcb_in_read with the condition that read(2) failed, I got several stack traces, see below.

> So if you see lots of EAGAINs from _xcb_in_read(), something (Xlib?) is doing
> lots of xcb_poll_for_event() calls.

This is exactly what is happening: Xlib is making a lot of unnecessary read(2) calls. It should only call read(2) when response is actually expected. From those stack traces it looks like _XReply calls read(2) one extra time, after the original response to the caller inquiry was already received. Such calls always necessarily return EAGAIN (unless server error or disconnect happens at this time). Therefore, such calls shouldn't even be made. Unnecessary system calls like these (as any unnecessary code) waste system resources.

This is an essence of this PR.

--- example stack traces ---
#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804512fee in poll_for_response (dpy=0x807dfb000) at xcb_io.c:288
#4  0x00000008045131fe in _XEventsQueued (dpy=0x807dfb000, mode=1) at xcb_io.c:362
#5  0x00000008045137a6 in _XFlush (dpy=0x807dfb000) at xcb_io.c:513
#6  0x00000008044dd205 in XCreateGC (dpy=0x807dfb000, d=346, valuemask=12, values=0x7fffffffbb30) at CrGC.c:89
#7  0x00000008044fa690 in XOpenDisplay (display=0x0) at OpenDis.c:533

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffbb30, extra=0, discard=0) at xcb_io.c:625
#4  0x00000008044fa837 in XOpenDisplay (display=0x0) at OpenDis.c:563

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffb9c0, extra=0, discard=1) at xcb_io.c:625
#4  0x000000080450351d in XQueryExtension (dpy=0x807dfb000, name=0x80461e631 "XKEYBOARD", major_opcode=0x7fffffffba14, first_event=0x7fffffffba18, first_error=0x7fffffffba1c) at QuExt.c:48
#5  0x00000008044f04eb in XInitExtension (dpy=0x807dfb000, name=0x80461e631 "XKEYBOARD") at InitExt.c:47
#6  0x00000008045945cb in XkbUseExtension (dpy=0x807dfb000, major_rtrn=0x0, minor_rtrn=0x0) at XKBUse.c:727
#7  0x00000008044fa98e in XOpenDisplay (display=0x0) at OpenDis.c:584

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffb9c0, extra=0, discard=1) at xcb_io.c:625
#4  0x000000080450351d in XQueryExtension (dpy=0x807dfb000, name=0x80461e631 "XKEYBOARD", major_opcode=0x7fffffffba14, first_event=0x7fffffffba18, first_error=0x7fffffffba1c) at QuExt.c:48
#5  0x00000008044f04eb in XInitExtension (dpy=0x807dfb000, name=0x80461e631 "XKEYBOARD") at InitExt.c:47
#6  0x00000008045945cb in XkbUseExtension (dpy=0x807dfb000, major_rtrn=0x0, minor_rtrn=0x0) at XKBUse.c:727
#7  0x00000008044fa98e in XOpenDisplay (display=0x0) at OpenDis.c:584

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffba60, extra=0, discard=0) at xcb_io.c:625
#4  0x000000080459477c in XkbUseExtension (dpy=0x807dfb000, major_rtrn=0x0, minor_rtrn=0x0) at XKBUse.c:743
#5  0x00000008044fa98e in XOpenDisplay (display=0x0) at OpenDis.c:584

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffbc50, extra=0, discard=1) at xcb_io.c:625
#4  0x000000080450351d in XQueryExtension (dpy=0x807dfb000, name=0x801553c47 "RENDER", major_opcode=0x807cca23c, first_event=0x7fffffffc6d0, first_error=0x7fffffffc6cc) at QuExt.c:48


#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffbb70, extra=0, discard=1) at xcb_io.c:625
#4  0x000000080450351d in XQueryExtension (dpy=0x807dfb000, name=0x804075a60 "RENDER", major_opcode=0x7fffffffbbc4, first_event=0x7fffffffbbc8, first_error=0x7fffffffbbcc) at QuExt.c:48
#5  0x00000008044f04eb in XInitExtension (dpy=0x807dfb000, name=0x804075a60 "RENDER") at InitExt.c:47
#6  0x0000000803e73c02 in XRenderFindDisplay () from /usr/local/lib/libXrender.so.1
#7  0x0000000803e74aa9 in XRenderQueryExtension () from /usr/local/lib/libXrender.so.1

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffbbb0, extra=0, discard=0) at xcb_io.c:625
#4  0x0000000803e741cf in XRenderQueryFormats () from /usr/local/lib/libXrender.so.1
#5  0x0000000803e74a4d in XRenderQueryVersion () from /usr/local/lib/libXrender.so.1

<after a while>
#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffc490, extra=0, discard=0) at xcb_io.c:625
#4  0x00000008044ead2f in XGetWindowProperty (dpy=0x807dfb000, w=138412037, property=256, offset=0, length=5, delete=0, req_type=256, actual_type=0x7fffffffc528, actual_format=0x7fffffffc534, nitems=0x7fffffffc520, bytesafter=0x7fffffffc518, prop=0x7fffffffc510) at GetProp.c:61
#5  0x0000000800ed5aa0 in GetMWMHints(_XDisplay*, unsigned long) () from /usr/local/lib/qt4/libQtGui.so.4
#6  0x0000000800ed98da in QWidgetPrivate::show_sys() () from /usr/local/lib/qt4/libQtGui.so.4



#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffbed0, extra=0, discard=1) at xcb_io.c:625
#4  0x000000080450cc90 in XSync (dpy=0x807dfb000, discard=0) at Sync.c:44
#5  0x0000000800eb2198 in QETWidget::translateConfigEvent(_XEvent const*) () from /usr/local/lib/qt4/libQtGui.so.4

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffabc0, extra=0, discard=1) at xcb_io.c:625
#4  0x000000080450f70f in XTranslateCoordinates (dpy=0x807dfb000, src_win=346, dest_win=138412037, src_x=456, src_y=244, dst_x=0x7fffffffac0c, dst_y=0x7fffffffac08, child=0x7fffffffac00) at TrCoords.c:51
#5  0x0000000800edacde in QWidgetPrivate::mapFromGlobal(QPoint const&) const () from /usr/local/lib/qt4/libQtGui.so.4

#0  _xcb_in_read (c=0x807e42000) at xcb_in.c:680
#1  0x00000008052af1c8 in xcb_poll_for_event (c=0x807e42000) at xcb_in.c:551
#2  0x0000000804512d3b in poll_for_event (dpy=0x807dfb000) at xcb_io.c:256
#3  0x0000000804513ca9 in _XReply (dpy=0x807dfb000, rep=0x7fffffffb210, extra=0, discard=1) at xcb_io.c:625
#4  0x00000008045037ea in XQueryPointer (dpy=0x807dfb000, w=346, root=0x7fffffffb298, child=0x7fffffffb290, root_x=0x7fffffffb2b4, root_y=0x7fffffffb2b0, win_x=0x7fffffffb2ac, win_y=0x7fffffffb2a8, mask=0x7fffffffb2a4) at QuPntr.c:48
#5  0x0000000800ec9d1d in QCursor::pos() () from /usr/local/lib/qt4/libQtGui.so.4
Comment 3 Julien Cristau 2012-07-05 11:29:51 UTC
not a bug.  xlib has to check for events in addition to replies, and those can come in at any point.  poll with a 0 timeout or non-blocking read makes no difference...
Comment 4 Yuri 2012-07-05 11:33:09 UTC
> not a bug.  xlib has to check for events in addition to replies, and those can
> come in at any point.  poll with a 0 timeout or non-blocking read makes no

Why does it have to check for event one more time after it just got reply?
Comment 5 Yuri 2012-07-05 11:36:54 UTC
I mean, when the read with the large enough buffer was made and it depleted all  data, why Xlib expects that some additional events will come immediately after this? I reopen this PR until explanation is provided.
Comment 6 Uli Schlachter 2012-07-05 12:29:58 UTC

*** This bug has been marked as a duplicate of bug 29561 ***


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.