From patchwork Fri Sep 11 16:10:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Herrmann X-Patchwork-Id: 7162481 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 602489F380 for ; Fri, 11 Sep 2015 16:11:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E9B9207CE for ; Fri, 11 Sep 2015 16:11:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 84579206F2 for ; Fri, 11 Sep 2015 16:11:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751539AbbIKQLP (ORCPT ); Fri, 11 Sep 2015 12:11:15 -0400 Received: from mail-wi0-f170.google.com ([209.85.212.170]:35676 "EHLO mail-wi0-f170.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750819AbbIKQLO (ORCPT ); Fri, 11 Sep 2015 12:11:14 -0400 Received: by wicge5 with SMTP id ge5so69139335wic.0 for ; Fri, 11 Sep 2015 09:11:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=W9r3FirO2J0ljf7oWlU4+zQXRkFbPemm4q1FGfRAZ2Q=; b=nfastsh3WqFfeccXtc+Vlr2Kg3Jo7late3hJzThIZvnN0zpq7XoEzIfSYulROcn+Zd vW5scVhMYm4DBpHOlrxXp5B+KEwte7VHQyKd5Ny7lPTxurvNBNdCh1H/4mTo2fEwbZ2y u+ph/Z1z5OxpkURdo7byPI/WSVggV2v54HcWEanqn20nghg5M3ZwvB466VzmTfxu/yeE oIvNAvAmj5KKxWG5lRC/NTiJojPjMbXi9RmCglKOO2DEeXIsDERAhljC9MpAocI6D3IB tdTleWklqE9m5IzGivpjJofPbuZjDi4L9AZ0qg0Y5KfVqRF536tDBlVOrtge+4ZS6TNL EJJQ== X-Received: by 10.180.186.195 with SMTP id fm3mr18674478wic.1.1441987873459; Fri, 11 Sep 2015 09:11:13 -0700 (PDT) Received: from david-t2.localdomain ([37.120.68.21]) by smtp.gmail.com with ESMTPSA id m4sm1101723wje.5.2015.09.11.09.11.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Sep 2015 09:11:11 -0700 (PDT) From: David Herrmann To: linux-fbdev@vger.kernel.org Cc: Jean-Christophe Plagniol-Villard , Tomi Valkeinen , dri-devel@lists.freedesktop.org, David Herrmann Subject: [PATCH] fbdev: put module after running driver callback Date: Fri, 11 Sep 2015 18:10:43 +0200 Message-Id: <1441987843-4313-1-git-send-email-dh.herrmann@gmail.com> X-Mailer: git-send-email 2.5.1 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, for each open() on an fbdev device, we pin the underlying fbdev device and driver module. On close(), we release both. This guarantees that the fbdev object stays around until the last FD is released (even though it might be unregistered already). However, currently we call module_put() *before* calling put_fb_info(). This has the side-effect that the driver module might be unloaded before put_fb_info() calls into fbinfo->fbops->fb_destroy(). Fix this by keeping the module pinned until after we release our fbdev reference. Note that register_framebuffer() and unregister_framebuffer() are special as we require the driver to unregister device before unloading. Hence, they don't need to pin the module. However, all open handlers *have to*. Signed-off-by: David Herrmann --- drivers/video/fbdev/core/fbmem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 0705d88..4e78731 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1482,13 +1482,16 @@ __acquires(&info->lock) __releases(&info->lock) { struct fb_info * const info = file->private_data; + struct module *owner; mutex_lock(&info->lock); if (info->fbops->fb_release) info->fbops->fb_release(info,1); - module_put(info->fbops->owner); + owner = info->fbops->owner; mutex_unlock(&info->lock); + put_fb_info(info); + module_put(owner); return 0; }