From mboxrd@z Thu Jan 1 00:00:00 1970 From: Joe Jin Date: Fri, 07 Jan 2011 10:20:54 +0000 Subject: [patch] xenfb: fix potential memory leak Message-Id: <4D26E906.3080608@oracle.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: jeremy@goop.org, ian.campbell@citrix.com, Andrew Morton Cc: linux-fbdev@vger.kernel.org, xen-devel@lists.xensource.com, gurudas.pai@oracle.com, guru.anbalagane@oracle.com, greg.marsden@oracle.com, joe.jin@oracle.com, linux-kernel@vger.kernel.org, Konrad Rzeszutek Wilk Hi, This patch fix potential memory leak when xenfb connect backend failed. Thanks for Ian's review and comments. Signed-off-by: Joe Jin Tested-by: Gurudas Pai Acked-by: Ian Campbell Cc: Jeremy Fitzhardinge Cc: Konrad Rzeszutek Wilk Cc: Andrew Morton --- xen-fbfront.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c index dc72563..953334a 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/xen-fbfront.c @@ -561,26 +561,24 @@ static void xenfb_init_shared_page(struct xenfb_info *info, static int xenfb_connect_backend(struct xenbus_device *dev, struct xenfb_info *info) { - int ret, evtchn; + int ret, evtchn, irq; struct xenbus_transaction xbt; ret = xenbus_alloc_evtchn(dev, &evtchn); if (ret) return ret; - ret = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, + irq = bind_evtchn_to_irqhandler(evtchn, xenfb_event_handler, 0, dev->devicetype, info); - if (ret < 0) { + if (irq < 0) { xenbus_free_evtchn(dev, evtchn); xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler"); - return ret; + return irq; } - info->irq = ret; - again: ret = xenbus_transaction_start(&xbt); if (ret) { xenbus_dev_fatal(dev, ret, "starting transaction"); - return ret; + goto unbind_irq; } ret = xenbus_printf(xbt, dev->nodename, "page-ref", "%lu", virt_to_mfn(info->page)); @@ -602,15 +600,18 @@ static int xenfb_connect_backend(struct xenbus_device *dev, if (ret = -EAGAIN) goto again; xenbus_dev_fatal(dev, ret, "completing transaction"); - return ret; + goto unbind_irq; } xenbus_switch_state(dev, XenbusStateInitialised); + info->irq = irq; return 0; error_xenbus: xenbus_transaction_end(xbt, 1); xenbus_dev_fatal(dev, ret, "writing xenstore"); + unbind_irq: + unbind_from_irqhandler(irq, info); return ret; }