From 70dba076926529a3b2230a71dc888fae61dec63b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 21 May 2013 16:44:07 +0300 Subject: [PATCH] math: put an escape hatch in handle_conditional_rl() In the kernel in mptbase_raid_process_event_data() there is a place which has 10 nested conditionals. To parse conditionals we need to break apart the condition and it's one of the more expensive things in Smatch. This is because you have implied states which need to be copied over and over. So I have put an escape hatch to give up on those cases if the memory is low. This is how all these cases where handled until yesterday so giving up here is not horrible. Signed-off-by: Dan Carpenter --- smatch_math.c | 5 +++++ smatch_slist.c | 7 +++++++ smatch_slist.h | 1 + 3 files changed, 13 insertions(+) diff --git a/smatch_math.c b/smatch_math.c index 54c49262..cede7298 100644 --- a/smatch_math.c +++ b/smatch_math.c @@ -476,6 +476,11 @@ static struct range_list *handle_conditional_rl(struct expression *expr, int imp if (implied_condition_false(expr->conditional)) return _get_rl(expr->cond_false, implied); + + /* this becomes a problem with deeply nested conditional statements */ + if (low_on_memory()) + return NULL; + type = get_type(expr); __push_fake_cur_slist(); diff --git a/smatch_slist.c b/smatch_slist.c index 248edcc2..13a7a562 100644 --- a/smatch_slist.c +++ b/smatch_slist.c @@ -197,6 +197,13 @@ int out_of_memory() return 0; } +int low_on_memory(void) +{ + if (sm_state_counter * sizeof(struct sm_state) >= 25000000) + return 1; + return 0; +} + static void free_sm_state(struct sm_state *sm) { free_slist(&sm->possible); diff --git a/smatch_slist.h b/smatch_slist.h index 5cb8f721..6785cdfa 100644 --- a/smatch_slist.h +++ b/smatch_slist.h @@ -61,6 +61,7 @@ struct smatch_state *get_state_stack(struct state_list_stack *stack, int owner, const char *name, struct symbol *sym); int out_of_memory(void); +int low_on_memory(void); void merge_slist(struct state_list **to, struct state_list *slist); void filter_slist(struct state_list **slist, struct state_list *filter); void and_slist_stack(struct state_list_stack **slist_stack); -- 2.11.4.GIT