From 17ff9389bd562b66e2292ac676bdcbc98ddea73b Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Mon, 17 Mar 2014 17:05:43 +0100 Subject: move waitqueue from endpoint to connection This way, we don't unnecessarily wake up all connection on an endpoint. Suggested by scampa.giovanni: http://code.google.com/p/d-bus/issues/detail?id=1 --- connection.c | 8 ++++++-- connection.h | 2 ++ endpoint.c | 7 ------- endpoint.h | 2 -- handle.c | 9 ++------- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/connection.c b/connection.c index 55e567cfb9d..99f7ee6df7f 100644 --- a/connection.c +++ b/connection.c @@ -705,7 +705,7 @@ static int kdbus_conn_queue_insert(struct kdbus_conn *conn, mutex_unlock(&conn->lock); /* wake up poll() */ - wake_up_interruptible(&conn->ep->wait); + wake_up_interruptible(&conn->wait); return 0; } @@ -1532,6 +1532,9 @@ int kdbus_conn_disconnect(struct kdbus_conn *conn, bool ensure_queue_empty) /* remove all names associated with this connection */ kdbus_name_remove_by_conn(conn->bus->name_registry, conn); + /* wake up the queue so that users can get a POLLERR */ + wake_up_interruptible(&conn->wait); + kdbus_notify_id_change(KDBUS_ITEM_ID_REMOVE, conn->id, conn->flags, ¬ify_list); @@ -1657,7 +1660,7 @@ int kdbus_conn_move_messages(struct kdbus_conn *conn_dst, mutex_unlock(&conn_dst->lock); /* wake up poll() */ - wake_up_interruptible(&conn_dst->ep->wait); + wake_up_interruptible(&conn_dst->wait); return ret; } @@ -1987,6 +1990,7 @@ int kdbus_conn_new(struct kdbus_ep *ep, atomic_set(&conn->reply_count, 0); INIT_DELAYED_WORK(&conn->work, kdbus_conn_work); conn->cred = current_cred(); + init_waitqueue_head(&conn->wait); /* init entry, so we can unconditionally remove it */ INIT_LIST_HEAD(&conn->monitor_entry); diff --git a/connection.h b/connection.h index 04f23c19e47..a7780d8efc9 100644 --- a/connection.h +++ b/connection.h @@ -56,6 +56,7 @@ * @msg_count: Number of queued messages * @reply_count: Number of requests this connection has issued, and * waits for replies from the peer + * @wait: Wake up this endpoint */ struct kdbus_conn { struct kref kref; @@ -88,6 +89,7 @@ struct kdbus_conn { size_t name_count; size_t msg_count; atomic_t reply_count; + wait_queue_head_t wait; }; struct kdbus_kmsg; diff --git a/endpoint.c b/endpoint.c index 3dc9b49ea7f..69718989b5d 100644 --- a/endpoint.c +++ b/endpoint.c @@ -85,12 +85,6 @@ void kdbus_ep_disconnect(struct kdbus_ep *ep) idr_remove(&ep->bus->domain->idr, ep->minor); ep->minor = 0; } - - /* - * wake up the queue so the connections can report - * POLLERR to their users. - */ - wake_up_interruptible(&ep->wait); } static void __kdbus_ep_free(struct kref *kref) @@ -167,7 +161,6 @@ int kdbus_ep_new(struct kdbus_bus *bus, const char *name, e->uid = uid; e->gid = gid; e->mode = mode; - init_waitqueue_head(&e->wait); e->name = kstrdup(name, GFP_KERNEL); if (!e->name) { diff --git a/endpoint.h b/endpoint.h index 7a5b41bbbbe..7385a095253 100644 --- a/endpoint.h +++ b/endpoint.h @@ -29,7 +29,6 @@ * @uid: UID owning this endpoint * @gid: GID owning this endpoint * @bus_entry: bus' endpoints - * @wait: Wake up this endpoint * @lock: Endpoint data lock * @user: Custom enpoints account against an anonymous user * @policy_db: Uploaded policy @@ -50,7 +49,6 @@ struct kdbus_ep { kuid_t uid; kgid_t gid; struct list_head bus_entry; - wait_queue_head_t wait; struct mutex lock; struct kdbus_domain_user *user; struct kdbus_policy_db *policy_db; diff --git a/handle.c b/handle.c index e0eb60943a9..b0b95aaea38 100644 --- a/handle.c +++ b/handle.c @@ -815,7 +815,6 @@ static unsigned int kdbus_handle_poll(struct file *file, struct kdbus_handle *handle = file->private_data; struct kdbus_conn *conn; unsigned int mask = 0; - bool disconnected; /* Only a connected endpoint can read/write data */ if (handle->type != KDBUS_HANDLE_EP_CONNECTED) @@ -823,15 +822,11 @@ static unsigned int kdbus_handle_poll(struct file *file, conn = handle->conn; - poll_wait(file, &conn->ep->wait, wait); + poll_wait(file, &conn->wait, wait); mutex_lock(&conn->lock); - mutex_lock(&conn->ep->lock); - disconnected = conn->ep->disconnected; - mutex_unlock(&conn->ep->lock); - - if (unlikely(disconnected)) + if (unlikely(conn->disconnected)) mask |= POLLERR | POLLHUP; else if (!list_empty(&conn->msg_list)) mask |= POLLIN | POLLRDNORM; -- cgit v1.2.3