Commit ba95c303 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-21167 LF_PINS::stack_ends_here inaccurate, leading to alloca() larger than stack

Use my_thread_var::stack_ends_here inside lf_pinbox_real_free() for address
where thread stack ends.

Remove LF_PINS::stack_ends_here.
It is not safe to assume that mysys_var that was used during pin allocation,
remains correct during free. E.g with binlog group commit in Innodb,
that frees pins for multiple Innodb transactions, it does not work
correctly.
parent 584ffa02
...@@ -65,7 +65,6 @@ typedef struct { ...@@ -65,7 +65,6 @@ typedef struct {
typedef struct { typedef struct {
void * volatile pin[LF_PINBOX_PINS]; void * volatile pin[LF_PINBOX_PINS];
LF_PINBOX *pinbox; LF_PINBOX *pinbox;
void **stack_ends_here;
void *purgatory; void *purgatory;
uint32 purgatory_count; uint32 purgatory_count;
uint32 volatile link; uint32 volatile link;
......
...@@ -151,7 +151,6 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox) ...@@ -151,7 +151,6 @@ void lf_pinbox_destroy(LF_PINBOX *pinbox)
*/ */
LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox) LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox)
{ {
struct st_my_thread_var *var;
uint32 pins, next, top_ver; uint32 pins, next, top_ver;
LF_PINS *el; LF_PINS *el;
/* /*
...@@ -194,12 +193,7 @@ LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox) ...@@ -194,12 +193,7 @@ LF_PINS *lf_pinbox_get_pins(LF_PINBOX *pinbox)
el->link= pins; el->link= pins;
el->purgatory_count= 0; el->purgatory_count= 0;
el->pinbox= pinbox; el->pinbox= pinbox;
var= my_thread_var;
/*
Threads that do not call my_thread_init() should still be
able to use the LF_HASH.
*/
el->stack_ends_here= (var ? & var->stack_ends_here : NULL);
return el; return el;
} }
...@@ -335,16 +329,18 @@ static void lf_pinbox_real_free(LF_PINS *pins) ...@@ -335,16 +329,18 @@ static void lf_pinbox_real_free(LF_PINS *pins)
void *list; void *list;
void **addr= NULL; void **addr= NULL;
void *first= NULL, *last= NULL; void *first= NULL, *last= NULL;
struct st_my_thread_var *var= my_thread_var;
void *stack_ends_here= var ? var->stack_ends_here : NULL;
LF_PINBOX *pinbox= pins->pinbox; LF_PINBOX *pinbox= pins->pinbox;
npins= pinbox->pins_in_array+1; npins= pinbox->pins_in_array+1;
#ifdef HAVE_ALLOCA #ifdef HAVE_ALLOCA
if (pins->stack_ends_here != NULL) if (stack_ends_here != NULL)
{ {
int alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins; int alloca_size= sizeof(void *)*LF_PINBOX_PINS*npins;
/* create a sorted list of pinned addresses, to speed up searches */ /* create a sorted list of pinned addresses, to speed up searches */
if (available_stack_size(&pinbox, *pins->stack_ends_here) > if (available_stack_size(&pinbox, stack_ends_here) >
alloca_size + ALLOCA_SAFETY_MARGIN) alloca_size + ALLOCA_SAFETY_MARGIN)
{ {
struct st_harvester hv; struct st_harvester hv;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment