block, bfq: use pointer entity->sched_data only if set

In the function __bfq_deactivate_entity, the pointer
entity->sched_data could happen to be used before being properly
initialized. This led to a NULL pointer dereference. This commit fixes
this bug by just using this pointer only where it is safe to do so.

Reported-by: Tom Harrison <l12436.tw@gmail.com>
Tested-by: Tom Harrison <l12436.tw@gmail.com>
Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
Paolo Valente 2017-05-09 11:37:27 +02:00 committed by Jens Axboe
parent fba704b494
commit a66c38a171

View File

@ -1114,12 +1114,21 @@ static void bfq_activate_requeue_entity(struct bfq_entity *entity,
bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree) bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
{ {
struct bfq_sched_data *sd = entity->sched_data; struct bfq_sched_data *sd = entity->sched_data;
struct bfq_service_tree *st = bfq_entity_service_tree(entity); struct bfq_service_tree *st;
int is_in_service = entity == sd->in_service_entity; bool is_in_service;
if (!entity->on_st) /* entity never activated, or already inactive */ if (!entity->on_st) /* entity never activated, or already inactive */
return false; return false;
/*
* If we get here, then entity is active, which implies that
* bfq_group_set_parent has already been invoked for the group
* represented by entity. Therefore, the field
* entity->sched_data has been set, and we can safely use it.
*/
st = bfq_entity_service_tree(entity);
is_in_service = entity == sd->in_service_entity;
if (is_in_service) if (is_in_service)
bfq_calc_finish(entity, entity->service); bfq_calc_finish(entity, entity->service);