Bluetooth: cmtp: Fix module reference
We cannot call module_put(THIS_MODULE) if this is our last reference. Otherwise, this call may cleanup our module before it returns. Gladly, the kthread API provides a simple wrapper for us. So lets use module_put_and_exit() to avoid a race condition with the module cleanup code. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
This commit is contained in:
parent
2ac654f740
commit
48b28b8db9
|
@ -67,14 +67,12 @@ static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
|
||||||
|
|
||||||
static void __cmtp_link_session(struct cmtp_session *session)
|
static void __cmtp_link_session(struct cmtp_session *session)
|
||||||
{
|
{
|
||||||
__module_get(THIS_MODULE);
|
|
||||||
list_add(&session->list, &cmtp_session_list);
|
list_add(&session->list, &cmtp_session_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __cmtp_unlink_session(struct cmtp_session *session)
|
static void __cmtp_unlink_session(struct cmtp_session *session)
|
||||||
{
|
{
|
||||||
list_del(&session->list);
|
list_del(&session->list);
|
||||||
module_put(THIS_MODULE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
|
static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
|
||||||
|
@ -327,6 +325,7 @@ static int cmtp_session(void *arg)
|
||||||
up_write(&cmtp_session_sem);
|
up_write(&cmtp_session_sem);
|
||||||
|
|
||||||
kfree(session);
|
kfree(session);
|
||||||
|
module_put_and_exit(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,9 +375,11 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
|
||||||
|
|
||||||
__cmtp_link_session(session);
|
__cmtp_link_session(session);
|
||||||
|
|
||||||
|
__module_get(THIS_MODULE);
|
||||||
session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d",
|
session->task = kthread_run(cmtp_session, session, "kcmtpd_ctr_%d",
|
||||||
session->num);
|
session->num);
|
||||||
if (IS_ERR(session->task)) {
|
if (IS_ERR(session->task)) {
|
||||||
|
module_put(THIS_MODULE);
|
||||||
err = PTR_ERR(session->task);
|
err = PTR_ERR(session->task);
|
||||||
goto unlink;
|
goto unlink;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue