On Wed, 31 Jan 2024, Tejun Heo wrote: > Hello, > > On Wed, Jan 31, 2024 at 10:19:07PM +0100, Mikulas Patocka wrote: > > > @@ -83,7 +83,7 @@ struct dm_verity_io { > > > struct bvec_iter iter; > > > > > > struct work_struct work; > > > - struct tasklet_struct tasklet; > > > + struct work_struct bh_work; > > > > > > /* > > > * Three variably-size fields follow this struct: > > > > Do we really need two separate work_structs here? They are never submitted > > concurrently, so I think that one would be enough. Or, am I missing > > something? > > I don't know, so just did the dumb thing. If the caller always guarantees > that the work items are never queued at the same time, reusing is fine. > However, the followings might be useful to keep on mind: > > - work_struct is pretty small - 4 pointers. > > - INIT_WORK() on a queued work item isn't gonna be pretty. > > - Flushing and no-concurrent-execution guarantee are broken on INIT_WORK(). > e.g. If you queue_work(), INIT_WORK(), flush_work(), the flush isn't > actually going to wait for the work item to finish. Also, if you do > queue_work(), INIT_WORK(), queue_work(), the two queued work item > instances may end up running concurrently. > > Muxing a single work item carries more risks of subtle bugs, but in some > cases, the way it's used is clear (e.g. sequential chaining) and that's > fine. The code doesn't call INIT_WORK() on a queued work item and it doesn't flush the workqueue (it destroys it only in a situation when there are no work items running) so I think it's safe to use just one work_struct. Mikulas