Revision 712f3147aee0fbbbbed2da20b21b272c5505125e authored by Linus Torvalds on 13 May 2011, 23:16:41 UTC, committed by Linus Torvalds on 14 May 2011, 17:23:44 UTC
When a register_framebuffer() call results in us removing old conflicting framebuffers, the new registration_lock doesn't protect that situation. And we can't just add the same locking to the function, because these functions call each other: register_framebuffer() calls remove_conflicting_framebuffers, which in turn calls unregister_framebuffer for any conflicting entry. In order to fix it, this just creates wrapper functions around all three functions and makes the versions that actually do the work be called "do_xxx()", leaving just the wrapper that gets the lock and calls the worker function. So the rule becomes simply that "do_xxxx()" has to be called with the lock held, and now do_register_framebuffer() can just call do_remove_conflicting_framebuffers(), and that in turn can call _do_unregister_framebuffer(), and there is no deadlock, and we can hold the registration lock over the whole sequence, fixing the races. It also makes error cases simpler, and fixes one situation where we would return from unregister_framebuffer() without releasing the lock, pointed out by Bruno Prémont. Tested-by: Bruno Prémont <bonbons@linux-vserver.org> Tested-by: Anca Emanuel <anca.emanuel@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent c47747f
ipv6.h
#ifndef _DCCP_IPV6_H
#define _DCCP_IPV6_H
/*
* net/dccp/ipv6.h
*
* An implementation of the DCCP protocol
* Copyright (c) 2005 Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/dccp.h>
#include <linux/ipv6.h>
struct dccp6_sock {
struct dccp_sock dccp;
/*
* ipv6_pinfo has to be the last member of dccp6_sock,
* see inet6_sk_generic.
*/
struct ipv6_pinfo inet6;
};
struct dccp6_request_sock {
struct dccp_request_sock dccp;
struct inet6_request_sock inet6;
};
struct dccp6_timewait_sock {
struct inet_timewait_sock inet;
struct inet6_timewait_sock tw6;
};
#endif /* _DCCP_IPV6_H */
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...