Note: This is a beta release of Red Hat Bugzilla 5.0. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Also email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback here.

Bug 232813

Summary: bluetoothd-service-input eats more than 90% cpu since kernel 2997
Product: [Fedora] Fedora Reporter: Patrick <rh_bugzilla>
Component: bluez-utilsAssignee: David Woodhouse <dwmw2>
Status: CLOSED RAWHIDE QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: rawhideCC: bjoeahan, marcel
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2007-07-21 10:51:38 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Patrick 2007-03-18 10:18:10 UTC
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):

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

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 14:14:49 UTC
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 04:44:06 UTC
Applied this fix from upstream to 3.9-2:;a=commitdiff;h=ccb51169867cc60e5141eb52792e239abc6c9f5e

Comment 3 David Woodhouse 2007-04-04 05:13:41 UTC
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 05:53:58 UTC
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);

Comment 5 Marcel Holtmann 2007-04-04 07:23:48 UTC
Actually if you return FALSE from session_event() it will remove it from the
GLib event loop.

Comment 6 David Woodhouse 2007-04-04 13:26:51 UTC
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 14:00:43 UTC
That is strange. Please show me the warning that you get.

Comment 8 David Woodhouse 2007-04-04 14:21:48 UTC
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 14:25:13 UTC
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 14:29:02 UTC
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 14:59:50 UTC
*** Bug 231716 has been marked as a duplicate of this bug. ***

Comment 12 David Woodhouse 2007-07-21 10:51:38 UTC
I believe this is now fixed.