From patchwork Tue Apr 9 13:01:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 10891231 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B7ABE17EF for ; Tue, 9 Apr 2019 13:04:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9FC9E283A6 for ; Tue, 9 Apr 2019 13:04:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9103228864; Tue, 9 Apr 2019 13:04:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 311F2283A6 for ; Tue, 9 Apr 2019 13:04:21 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hDqO5-00052L-Je; Tue, 09 Apr 2019 13:02:05 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hDqO4-00052G-2L for xen-devel@lists.xenproject.org; Tue, 09 Apr 2019 13:02:04 +0000 X-Inumbo-ID: aab744f0-5ac7-11e9-92d7-bc764e045a96 Received: from prv1-mh.provo.novell.com (unknown [137.65.248.33]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id aab744f0-5ac7-11e9-92d7-bc764e045a96; Tue, 09 Apr 2019 13:02:02 +0000 (UTC) Received: from INET-PRV1-MTA by prv1-mh.provo.novell.com with Novell_GroupWise; Tue, 09 Apr 2019 07:02:01 -0600 Message-Id: <5CAC97C30200007800225DED@prv1-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 18.1.0 Date: Tue, 09 Apr 2019 07:01:55 -0600 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Content-Disposition: inline Subject: [Xen-devel] [PATCH] timers: limit heap size X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP First and foremost make timer_softirq_action() avoid growing the heap if its new size can't be stored without truncation. 64k entries is a lot, and I don't think we're at high risk of running into the issue, but I think it's better to not allow for hard to debug problems to occur in the first place. Furthermore also adjust the code such the size/limit fields becoming unsigned int would at least work from a mere sizing point of view. For this also switch various uses of plain int to unsigned int. Signed-off-by: Jan Beulich --- a/xen/common/timer.c +++ b/xen/common/timer.c @@ -63,9 +63,9 @@ static struct heap_metadata *heap_metada } /* Sink down element @pos of @heap. */ -static void down_heap(struct timer **heap, int pos) +static void down_heap(struct timer **heap, unsigned int pos) { - int sz = heap_metadata(heap)->size, nxt; + unsigned int sz = heap_metadata(heap)->size, nxt; struct timer *t = heap[pos]; while ( (nxt = (pos << 1)) <= sz ) @@ -84,7 +84,7 @@ static void down_heap(struct timer **hea } /* Float element @pos up @heap. */ -static void up_heap(struct timer **heap, int pos) +static void up_heap(struct timer **heap, unsigned int pos) { struct timer *t = heap[pos]; @@ -103,8 +103,8 @@ static void up_heap(struct timer **heap, /* Delete @t from @heap. Return TRUE if new top of heap. */ static int remove_from_heap(struct timer **heap, struct timer *t) { - int sz = heap_metadata(heap)->size; - int pos = t->heap_offset; + unsigned int sz = heap_metadata(heap)->size; + unsigned int pos = t->heap_offset; if ( unlikely(pos == sz) ) { @@ -130,7 +130,7 @@ static int remove_from_heap(struct timer /* Add new entry @t to @heap. Return TRUE if new top of heap. */ static int add_to_heap(struct timer **heap, struct timer *t) { - int sz = heap_metadata(heap)->size; + unsigned int sz = heap_metadata(heap)->size; /* Fail if the heap is full. */ if ( unlikely(sz == heap_metadata(heap)->limit) ) @@ -463,9 +463,14 @@ static void timer_softirq_action(void) if ( unlikely(ts->list != NULL) ) { /* old_limit == (2^n)-1; new_limit == (2^(n+4))-1 */ - int old_limit = heap_metadata(heap)->limit; - int new_limit = ((old_limit + 1) << 4) - 1; - struct timer **newheap = xmalloc_array(struct timer *, new_limit + 1); + unsigned int old_limit = heap_metadata(heap)->limit; + unsigned int new_limit = ((old_limit + 1) << 4) - 1; + struct timer **newheap = NULL; + + /* Don't grow the heap beyond what is representable in its metadata. */ + if ( new_limit == (typeof(heap_metadata(heap)->limit))new_limit && + new_limit + 1 ) + newheap = xmalloc_array(struct timer *, new_limit + 1); if ( newheap != NULL ) { spin_lock_irq(&ts->lock); @@ -544,7 +549,7 @@ static void dump_timerq(unsigned char ke struct timers *ts; unsigned long flags; s_time_t now = NOW(); - int i, j; + unsigned int i, j; printk("Dumping timer queues:\n"); @@ -556,7 +561,7 @@ static void dump_timerq(unsigned char ke spin_lock_irqsave(&ts->lock, flags); for ( j = 1; j <= heap_metadata(ts->heap)->size; j++ ) dump_timer(ts->heap[j], now); - for ( t = ts->list, j = 0; t != NULL; t = t->list_next, j++ ) + for ( t = ts->list; t != NULL; t = t->list_next ) dump_timer(t, now); spin_unlock_irqrestore(&ts->lock, flags); }