block/elevator: reduce the critical section
PATCH 1/1 block/elevator: reduce the critical section
1.reduce the critical section in elevator_get(). 2.reduce the critical section in elevator_get_by_features(). 3.remove the found variable.
the elv_list_lock is used to protect the elv_list, and the operations of elevator_type does not need to be protected.
--- block/elevator.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
block/elevator.c +6 -8
@@ -151,11 +151,11 @@ static struct elevator_type *elevator_get(struct request_queue *q,spin_lock (&elv_list_lock); e =elevator_find (name, q->required_elevator_features); } +spin_unlock (&elv_list_lock);if (e && !try_module_get (e->elevator_owner)) e =NULL ; -spin_unlock (&elv_list_lock);return e; }
@@ -633,23 +633,21 @@ static struct elevator_type *elevator_get_default(struct request_queue *q)*/ static struct elevator_type *elevator_get_by_features (struct request_queue *q) { -struct elevator_type *e, *found =NULL ; +struct elevator_type *e =NULL ;spin_lock (&elv_list_lock); -list_for_each_entry (e, &elv_list, list) {if (elv_support_features (e->elevator_features, q->required_elevator_features)) { - found = e;break ; } } +spin_unlock (&elv_list_lock); -if (found && !try_module_get (found->elevator_owner)) - found =NULL ; +if (e && !try_module_get (e->elevator_owner)) + e =NULL ; -spin_unlock (&elv_list_lock); -return found; +return e; }/*
Signature · 1 line
2.25.1
Jens Axboe
maintainerQuoted 19 lines · Hui Su
1.reduce the critical section in
elevator_get(). 2.reduce the critical section inelevator_get_by_features(). 3.remove the found variable.the
elv_list_lockis used to protect theelv_list, and the operations ofelevator_typedoes not need to be protected.Signed-off-by Hui Su <[email protected]>--- block/elevator.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)block/elevator.c +0
-0@@ -151,11 +151,11 @@ static struct elevator_type *elevator_get(struct request_queue *q,spin_lock (&elv_list_lock);
block/elevator.c static struct elevator_type *elevator_get(struct request_queue *q, · line 160
Quoted 10 lines
block/elevator.c +1
-1e =elevator_find (name, q->required_elevator_features); } +spin_unlock (&elv_list_lock);if (e && !try_module_get (e->elevator_owner)) e =NULL ; -spin_unlock (&elv_list_lock);return e; }
What happens for:
A B spin_unlock(&elv_list_lock); rmmod -> elv_unregister(); try_module_get();
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerQuoted 17 lines · Hui Su
block/elevator.c +2
-3@@ -633,23 +633,21 @@ static struct elevator_type *elevator_get_default(struct request_queue *q)*/ static struct elevator_type *elevator_get_by_features (struct request_queue *q) { -struct elevator_type *e, *found =NULL ; +struct elevator_type *e =NULL ;spin_lock (&elv_list_lock); -list_for_each_entry (e, &elv_list, list) {if (elv_support_features (e->elevator_features, q->required_elevator_features)) { - found = e;break ; } } +spin_unlock (&elv_list_lock);
block/elevator.c static struct elevator_type *elevator_get_default(struct request_queue *q) · line 651
Quoted 10 lines
block/elevator.c +3
-4-if (found && !try_module_get (found->elevator_owner)) - found =NULL ; +if (e && !try_module_get (e->elevator_owner)) + e =NULL ; -spin_unlock (&elv_list_lock); -return found; +return e; }
This looks wrong as well. If we don't match the elevator, then we just return the last one. Or maybe even a totally invalid entry, depending on how the list iteration works.
Signature · 1 line
Jens Axboe