Bug 232813 - bluetoothd-service-input eats more than 90% cpu since kernel 2997
bluetoothd-service-input eats more than 90% cpu since kernel 2997
Status: CLOSED RAWHIDE
Product: Fedora
Classification: Fedora
Component: bluez-utils (Show other bugs)
rawhide
All Linux
medium Severity medium
: ---
: ---
Assigned To: David Woodhouse
:
: 231716 (view as bug list)
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2007-03-18 06:18 EDT by Patrick
Modified: 2007-11-30 17:11 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2007-07-21 06:51:38 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Patrick 2007-03-18 06:18:10 EDT
Description of problem:
bluetoothd-service-input eats more than 90% cpu since kernel 2997. See Bug
227893 too.

Version-Release number of selected component (if applicable):
bluez-utils-3.9-1.fc7

How reproducible:
Boot the laptop with the 2997 kernel and the bluetooth service enabled

Steps to Reproduce:
1. boot laptop with bluetooth hardbutton on laptop turned on
2. wait for boot to finish & login
3. top shows that bluetoothd-service-input eats most of the cpu
  
Actual results:
From top: 1579 root      25   0  2708  996  892 R 94.7  0.1  55:14.68
bluetoothd-serv

Expected results:
bluetoothd-service-input does not use more than 90% of cpu all the time

Additional info:
strace of the process shows:
poll([{fd=4, events=POLLIN}, {fd=7, events=POLLIN, revents=POLLNVAL}, {fd=5,
events=POLLIN}, {fd=6, events=POLLIN}], 4, -1) =  1
Comment 1 Marcel Holtmann 2007-03-19 10:14:49 EDT
This bug is due to the use of the system GLib and a mistake in not providing the
G_IO_HUP, G_IO_ERR and G_IO_NVAL flags to the g_io_add_watch() call. It was
working fine with our re-implementation of the GLib mainloop, but with the
system GLib it causes problems. Hopefully all of them should be fixed in the CVS.
Comment 2 David Woodhouse 2007-04-04 00:44:06 EDT
Applied this fix from upstream to 3.9-2:

http://git.infradead.org/?p=bluez-utils.git;a=commitdiff;h=ccb51169867cc60e5141eb52792e239abc6c9f5e
Comment 3 David Woodhouse 2007-04-04 01:13:41 EDT
That doesn't help (and I didn't commit it after it failed testing).

Current bluez-utils from the git tree is still suffering the same problem.
Comment 4 David Woodhouse 2007-04-04 01:53:58 EDT
This stops it eating CPU, although there's still a warning. It's closing the
control socket for an incoming connection without ever deregistering it from the
glib event loop.

diff --git a/input/server.c b/input/server.c
index b140bb6..911fc8e 100644
--- a/input/server.c
+++ b/input/server.c
@@ -69,7 +69,7 @@ static struct session_data *find_session(bdaddr_t *src,
bdaddr_t *dst)
 
 static gboolean session_event(GIOChannel *chan, GIOCondition cond, gpointer data)
 {
-       if (cond & (G_IO_HUP | G_IO_ERR))
+       if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
                return FALSE;
 
        return TRUE;
@@ -133,7 +133,7 @@ static void create_watch(int sk, struct session_data *session)
        io = g_io_channel_unix_new(sk);
        g_io_channel_set_close_on_unref(io, TRUE);
 
-       g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR,
+       g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
                                                session_event, session);
 
        g_io_channel_unref(io);
Comment 5 Marcel Holtmann 2007-04-04 03:23:48 EDT
Actually if you return FALSE from session_event() it will remove it from the
GLib event loop.
Comment 6 David Woodhouse 2007-04-04 09:26:51 EDT
Yes, but it still gives me one warning about selecting on an invalid fd. We
should remove the fd in question from the glib watch list when we close it at
the end of create_device().
Comment 7 Marcel Holtmann 2007-04-04 10:00:43 EDT
That is strange. Please show me the warning that you get.
Comment 8 David Woodhouse 2007-04-04 10:21:48 EDT
input[21982]: Bluetooth Input daemon
input[21982]: Registered input manager path:/org/bluez/input
input[21982]: Created input device: /org/bluez/input/pointing0
input[21982]: Created input device: /org/bluez/input/keyboard1
input[21982]: Incoming connection on PSM 17
input[21982]: Incoming connection on PSM 19
input[21982]: New input device 00:0A:94:C0:7E:17 (CSR HIDEngine Three Button Mouse)

(process:21982): GLib-WARNING **: Invalid file descriptor.
Comment 9 David Woodhouse 2007-04-04 10:25:13 EDT
I think it happens when glib tries to close the file descriptor after we return
FALSE from session_event()...

send(3, "<30>Apr  4 10:22:15 input[22013]"..., 103, MSG_NOSIGNAL) = 103
ioctl(9, 0x800448c8, 0x7f9320e4)        = 9
ioctl(9, 0x800448c8, 0x7f9320e4)        = 0
close(9)                                = 0
close(8)                                = 0
close(7)                                = 0
poll([{fd=4, events=POLLIN}, {fd=7, events=POLLIN, revents=POLLNVAL}, {fd=5,
events=POLLIN}, {fd=6, events=POLLIN}], 4, -1) = 1
close(7)                                = -1 EBADF (Bad file descriptor)
...
write(2, "\n(process:22013): GLib-WARNING *"..., 61) = 61
Comment 10 Marcel Holtmann 2007-04-04 10:29:02 EDT
This could be caused by g_io_channel_set_close_on_unref() we use. So we better
not use it and return FALSE in case of G_IO_NVAL and in case of G_IO_HUP |
G_IO_ERR we call g_io_channel_close() in the callback.
Comment 11 Bjørn Are Hansen 2007-04-05 10:59:50 EDT
*** Bug 231716 has been marked as a duplicate of this bug. ***
Comment 12 David Woodhouse 2007-07-21 06:51:38 EDT
I believe this is now fixed.

Note You need to log in before you can comment on or make changes to this bug.