Re: [Xen-devel] Ping: [PATCH v2] timers: limit heap size

2019-07-15 Thread Roger Pau Monné
On Fri, Jul 05, 2019 at 04:06:06PM +, Jan Beulich wrote:
> >>> On 05.06.19 at 08:51,  wrote:
> > 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 risk of actually running into the issue,
> > but I also think it's better not to 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 

Thanks:

Reviewed-by: Roger Pau Monné 

I however wonder whether all this heap timer management plus the extra
list is really the best option, using a balanced tree seems like a
better option here.

Roger.

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] Ping²: [PATCH v2] timers: limit heap size

2019-07-15 Thread Jan Beulich
On 05.07.2019 18:06, Jan Beulich wrote:
 On 05.06.19 at 08:51,  wrote:
>> 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 risk of actually running into the issue,
>> but I also think it's better not to 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 
>> ---
>> v2: Log (once) when heap limit would have been exceeded.
>>
>> --- 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,17 @@ 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);
>> +else
>> +printk_once(XENLOG_WARNING "CPU%u: timer heap limit reached\n",
>> +smp_processor_id());
>>   if ( newheap != NULL )
>>   {
>>   spin_lock_irq(>lock);
>> @@ -544,7 +549,7 @@ static void dump_timerq(unsigned char ke
>>   struct timers *ts;
>>   unsigned long  flags;
>>   s_time_t   now = NOW();
>> -inti, j;
>> +unsigned int   i, j;
>>   
>>   printk("Dumping timer queues:\n");
>>   
>> @@ -556,7 +561,7 @@ static void dump_timerq(unsigned char ke
>>   spin_lock_irqsave(>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(>lock, flags);
>>   }
>>
>>
>>
>>
> ___
> Xen-devel mailing list
> Xen-devel@lists.xenproject.org
> https://lists.xenproject.org/mailman/listinfo/xen-devel
> 

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] Ping: [PATCH v2] timers: limit heap size

2019-07-05 Thread Jan Beulich
>>> On 05.06.19 at 08:51,  wrote:
> 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 risk of actually running into the issue,
> but I also think it's better not to 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 
> ---
> v2: Log (once) when heap limit would have been exceeded.
> 
> --- 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,17 @@ 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);
> +else
> +printk_once(XENLOG_WARNING "CPU%u: timer heap limit reached\n",
> +smp_processor_id());
>  if ( newheap != NULL )
>  {
>  spin_lock_irq(>lock);
> @@ -544,7 +549,7 @@ static void dump_timerq(unsigned char ke
>  struct timers *ts;
>  unsigned long  flags;
>  s_time_t   now = NOW();
> -inti, j;
> +unsigned int   i, j;
>  
>  printk("Dumping timer queues:\n");
>  
> @@ -556,7 +561,7 @@ static void dump_timerq(unsigned char ke
>  spin_lock_irqsave(>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(>lock, flags);
>  }
> 
> 
> 
> 
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel