Questioned GEOM bioq_* usage necessity in some modules: g_concat, g_mirror, g_stripe ...

I'm developing GEOM provider/consumer and looking through the existing code to learn. And in process of that started to question the usage necessity of bio queue (bio_queue_head) in some cases.

There are a lot of cases when a pattern for functions such as g_*_read or g_*_flush is like so:
Code:
..
struct bio_queue_head queue;
..
bioq_init(&queue);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
  ..
  bioq_insert_tail(&queue, cloned_bp);
  ..
}
while ((cbp = bioq_takefirst(&queue)) != NULL) {
  ..
  g_io_request(cloned_bp, disk->d_consumer);
  ..
}
..

For example:
./sys/geom/mirror/g_mirror.c:1073 g_mirror_flush(..)
./sys/geom/concat/g_concat.c:1382 g_raid3_flush(..)
./sys/geom/concat/g_concat.c:262 g_concat_flush(..)
./sys/geom/concat/g_concat.c:294 g_concat_start(..)
./sys/geom/raid/tr_raid5.c:207 g_raid_tr_iostart_raid5_read(..)
./sys/geom/stripe/g_stripe.c:535 g_stripe_flush(..)
..

There are some in my opinion valid usecases, ./sys/geom/gate/g_gate.c, bio queue is stored within softc and used across the code bioq_init(&sc->sc_inqueue). That is logical, queue is used for queuing purposes across the threads and function calls. But in the previous mentioned ones, i just can not see the necessity for using a queue.

Isn't it just a useless overhead? Why couldn't the g_io_request be done within first loop at the correct positions? Because the queue is never ever used outside of the function it is defined.

Looping mechanisms used in mentioned codes are different: while, for, TAILQ_FOREACH, LIST_FOREACH, etc., but the pattern generally used is the same.
 
Questions like this are probably best asked on the mailing lists. There aren't a lot of FreeBSD developers on this board unfortunately.
 
Back
Top