diff options
author | Paolo Valente <paolo.valente@linaro.org> | 2017-05-09 11:37:27 +0200 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2017-05-10 07:39:43 -0600 |
commit | a66c38a171ed25488debf80247a9e72e1026e82c (patch) | |
tree | 52c407a83f2706d34e5ced556903bcb5939265dc /block/bfq-wf2q.c | |
parent | fba704b494fdc6816a039a66887274b4e5c00eeb (diff) | |
download | linux-a66c38a171ed25488debf80247a9e72e1026e82c.tar.gz linux-a66c38a171ed25488debf80247a9e72e1026e82c.tar.bz2 linux-a66c38a171ed25488debf80247a9e72e1026e82c.zip |
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>
Diffstat (limited to 'block/bfq-wf2q.c')
-rw-r--r-- | block/bfq-wf2q.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c index b4fc3e4260b7..8726ede19eef 100644 --- a/block/bfq-wf2q.c +++ b/block/bfq-wf2q.c @@ -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) { struct bfq_sched_data *sd = entity->sched_data; - struct bfq_service_tree *st = bfq_entity_service_tree(entity); - int is_in_service = entity == sd->in_service_entity; + struct bfq_service_tree *st; + bool is_in_service; if (!entity->on_st) /* entity never activated, or already inactive */ 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) bfq_calc_finish(entity, entity->service); |