3636 ZLOOP_OPT_ZONE_APPEND = (1 << 9 ),
3737 ZLOOP_OPT_ORDERED_ZONE_APPEND = (1 << 10 ),
3838 ZLOOP_OPT_DISCARD_WRITE_CACHE = (1 << 11 ),
39+ ZLOOP_OPT_MAX_OPEN_ZONES = (1 << 12 ),
3940};
4041
4142static const match_table_t zloop_opt_tokens = {
@@ -51,6 +52,7 @@ static const match_table_t zloop_opt_tokens = {
5152 { ZLOOP_OPT_ZONE_APPEND , "zone_append=%u" },
5253 { ZLOOP_OPT_ORDERED_ZONE_APPEND , "ordered_zone_append" },
5354 { ZLOOP_OPT_DISCARD_WRITE_CACHE , "discard_write_cache" },
55+ { ZLOOP_OPT_MAX_OPEN_ZONES , "max_open_zones=%u" },
5456 { ZLOOP_OPT_ERR , NULL }
5557};
5658
@@ -59,6 +61,7 @@ static const match_table_t zloop_opt_tokens = {
5961#define ZLOOP_DEF_ZONE_SIZE ((256ULL * SZ_1M) >> SECTOR_SHIFT)
6062#define ZLOOP_DEF_NR_ZONES 64
6163#define ZLOOP_DEF_NR_CONV_ZONES 8
64+ #define ZLOOP_DEF_MAX_OPEN_ZONES 0
6265#define ZLOOP_DEF_BASE_DIR "/var/local/zloop"
6366#define ZLOOP_DEF_NR_QUEUES 1
6467#define ZLOOP_DEF_QUEUE_DEPTH 128
@@ -76,6 +79,7 @@ struct zloop_options {
7679 sector_t zone_size ;
7780 sector_t zone_capacity ;
7881 unsigned int nr_conv_zones ;
82+ unsigned int max_open_zones ;
7983 char * base_dir ;
8084 unsigned int nr_queues ;
8185 unsigned int queue_depth ;
@@ -99,7 +103,12 @@ enum zloop_zone_flags {
99103 ZLOOP_ZONE_SEQ_ERROR ,
100104};
101105
106+ /*
107+ * Zone descriptor.
108+ * Locking order: z.lock -> z.wp_lock -> zlo.open_zones_lock
109+ */
102110struct zloop_zone {
111+ struct list_head open_zone_entry ;
103112 struct file * file ;
104113
105114 unsigned long flags ;
@@ -133,8 +142,13 @@ struct zloop_device {
133142 sector_t zone_capacity ;
134143 unsigned int nr_zones ;
135144 unsigned int nr_conv_zones ;
145+ unsigned int max_open_zones ;
136146 unsigned int block_size ;
137147
148+ spinlock_t open_zones_lock ;
149+ struct list_head open_zones_lru_list ;
150+ unsigned int nr_open_zones ;
151+
138152 struct zloop_zone zones [] __counted_by (nr_zones );
139153};
140154
@@ -158,6 +172,122 @@ static unsigned int rq_zone_no(struct request *rq)
158172 return blk_rq_pos (rq ) >> zlo -> zone_shift ;
159173}
160174
175+ /*
176+ * Open an already open zone. This is mostly a no-op, except for the imp open ->
177+ * exp open condition change that may happen. We also move a zone at the tail of
178+ * the list of open zones so that if we need to
179+ * implicitly close one open zone, we can do so in LRU order.
180+ */
181+ static inline void zloop_lru_rotate_open_zone (struct zloop_device * zlo ,
182+ struct zloop_zone * zone )
183+ {
184+ if (zlo -> max_open_zones ) {
185+ spin_lock (& zlo -> open_zones_lock );
186+ list_move_tail (& zone -> open_zone_entry ,
187+ & zlo -> open_zones_lru_list );
188+ spin_unlock (& zlo -> open_zones_lock );
189+ }
190+ }
191+
192+ static inline void zloop_lru_remove_open_zone (struct zloop_device * zlo ,
193+ struct zloop_zone * zone )
194+ {
195+ if (zone -> cond == BLK_ZONE_COND_IMP_OPEN ||
196+ zone -> cond == BLK_ZONE_COND_EXP_OPEN ) {
197+ spin_lock (& zlo -> open_zones_lock );
198+ list_del_init (& zone -> open_zone_entry );
199+ zlo -> nr_open_zones -- ;
200+ spin_unlock (& zlo -> open_zones_lock );
201+ }
202+ }
203+
204+ static inline bool zloop_can_open_zone (struct zloop_device * zlo )
205+ {
206+ return !zlo -> max_open_zones || zlo -> nr_open_zones < zlo -> max_open_zones ;
207+ }
208+
209+ /*
210+ * If we have reached the maximum open zones limit, attempt to close an
211+ * implicitly open zone (if we have any) so that we can implicitly open another
212+ * zone without exceeding the maximum number of open zones.
213+ */
214+ static bool zloop_close_imp_open_zone (struct zloop_device * zlo )
215+ {
216+ struct zloop_zone * zone ;
217+
218+ lockdep_assert_held (& zlo -> open_zones_lock );
219+
220+ if (zloop_can_open_zone (zlo ))
221+ return true;
222+
223+ list_for_each_entry (zone , & zlo -> open_zones_lru_list , open_zone_entry ) {
224+ if (zone -> cond == BLK_ZONE_COND_IMP_OPEN ) {
225+ zone -> cond = BLK_ZONE_COND_CLOSED ;
226+ list_del_init (& zone -> open_zone_entry );
227+ zlo -> nr_open_zones -- ;
228+ return true;
229+ }
230+ }
231+
232+ return false;
233+ }
234+
235+ static bool zloop_open_closed_or_empty_zone (struct zloop_device * zlo ,
236+ struct zloop_zone * zone ,
237+ bool explicit )
238+ {
239+ spin_lock (& zlo -> open_zones_lock );
240+
241+ if (explicit ) {
242+ /*
243+ * Explicit open: we cannot allow this if we have reached the
244+ * maximum open zones limit.
245+ */
246+ if (!zloop_can_open_zone (zlo ))
247+ goto fail ;
248+ zone -> cond = BLK_ZONE_COND_EXP_OPEN ;
249+ } else {
250+ /*
251+ * Implicit open case: if we have reached the maximum open zones
252+ * limit, try to close an implicitly open zone first.
253+ */
254+ if (!zloop_close_imp_open_zone (zlo ))
255+ goto fail ;
256+ zone -> cond = BLK_ZONE_COND_IMP_OPEN ;
257+ }
258+
259+ zlo -> nr_open_zones ++ ;
260+ list_add_tail (& zone -> open_zone_entry ,
261+ & zlo -> open_zones_lru_list );
262+
263+ spin_unlock (& zlo -> open_zones_lock );
264+
265+ return true;
266+
267+ fail :
268+ spin_unlock (& zlo -> open_zones_lock );
269+
270+ return false;
271+ }
272+
273+ static bool zloop_do_open_zone (struct zloop_device * zlo ,
274+ struct zloop_zone * zone , bool explicit )
275+ {
276+ switch (zone -> cond ) {
277+ case BLK_ZONE_COND_IMP_OPEN :
278+ case BLK_ZONE_COND_EXP_OPEN :
279+ if (explicit )
280+ zone -> cond = BLK_ZONE_COND_EXP_OPEN ;
281+ zloop_lru_rotate_open_zone (zlo , zone );
282+ return true;
283+ case BLK_ZONE_COND_EMPTY :
284+ case BLK_ZONE_COND_CLOSED :
285+ return zloop_open_closed_or_empty_zone (zlo , zone , explicit );
286+ default :
287+ return false;
288+ }
289+ }
290+
161291static int zloop_update_seq_zone (struct zloop_device * zlo , unsigned int zone_no )
162292{
163293 struct zloop_zone * zone = & zlo -> zones [zone_no ];
@@ -191,13 +321,17 @@ static int zloop_update_seq_zone(struct zloop_device *zlo, unsigned int zone_no)
191321
192322 spin_lock_irqsave (& zone -> wp_lock , flags );
193323 if (!file_sectors ) {
324+ zloop_lru_remove_open_zone (zlo , zone );
194325 zone -> cond = BLK_ZONE_COND_EMPTY ;
195326 zone -> wp = zone -> start ;
196327 } else if (file_sectors == zlo -> zone_capacity ) {
328+ zloop_lru_remove_open_zone (zlo , zone );
197329 zone -> cond = BLK_ZONE_COND_FULL ;
198330 zone -> wp = ULLONG_MAX ;
199331 } else {
200- zone -> cond = BLK_ZONE_COND_CLOSED ;
332+ if (zone -> cond != BLK_ZONE_COND_IMP_OPEN &&
333+ zone -> cond != BLK_ZONE_COND_EXP_OPEN )
334+ zone -> cond = BLK_ZONE_COND_CLOSED ;
201335 zone -> wp = zone -> start + file_sectors ;
202336 }
203337 spin_unlock_irqrestore (& zone -> wp_lock , flags );
@@ -221,19 +355,8 @@ static int zloop_open_zone(struct zloop_device *zlo, unsigned int zone_no)
221355 goto unlock ;
222356 }
223357
224- switch (zone -> cond ) {
225- case BLK_ZONE_COND_EXP_OPEN :
226- break ;
227- case BLK_ZONE_COND_EMPTY :
228- case BLK_ZONE_COND_CLOSED :
229- case BLK_ZONE_COND_IMP_OPEN :
230- zone -> cond = BLK_ZONE_COND_EXP_OPEN ;
231- break ;
232- case BLK_ZONE_COND_FULL :
233- default :
358+ if (!zloop_do_open_zone (zlo , zone , true))
234359 ret = - EIO ;
235- break ;
236- }
237360
238361unlock :
239362 mutex_unlock (& zone -> lock );
@@ -264,6 +387,7 @@ static int zloop_close_zone(struct zloop_device *zlo, unsigned int zone_no)
264387 case BLK_ZONE_COND_IMP_OPEN :
265388 case BLK_ZONE_COND_EXP_OPEN :
266389 spin_lock_irqsave (& zone -> wp_lock , flags );
390+ zloop_lru_remove_open_zone (zlo , zone );
267391 if (zone -> wp == zone -> start )
268392 zone -> cond = BLK_ZONE_COND_EMPTY ;
269393 else
@@ -305,6 +429,7 @@ static int zloop_reset_zone(struct zloop_device *zlo, unsigned int zone_no)
305429 }
306430
307431 spin_lock_irqsave (& zone -> wp_lock , flags );
432+ zloop_lru_remove_open_zone (zlo , zone );
308433 zone -> cond = BLK_ZONE_COND_EMPTY ;
309434 zone -> wp = zone -> start ;
310435 clear_bit (ZLOOP_ZONE_SEQ_ERROR , & zone -> flags );
@@ -352,6 +477,7 @@ static int zloop_finish_zone(struct zloop_device *zlo, unsigned int zone_no)
352477 }
353478
354479 spin_lock_irqsave (& zone -> wp_lock , flags );
480+ zloop_lru_remove_open_zone (zlo , zone );
355481 zone -> cond = BLK_ZONE_COND_FULL ;
356482 zone -> wp = ULLONG_MAX ;
357483 clear_bit (ZLOOP_ZONE_SEQ_ERROR , & zone -> flags );
@@ -478,9 +604,10 @@ static int zloop_seq_write_prep(struct zloop_cmd *cmd)
478604 }
479605
480606 /* Implicitly open the target zone. */
481- if (zone -> cond == BLK_ZONE_COND_CLOSED ||
482- zone -> cond == BLK_ZONE_COND_EMPTY )
483- zone -> cond = BLK_ZONE_COND_IMP_OPEN ;
607+ if (!zloop_do_open_zone (zlo , zone , false)) {
608+ ret = - EIO ;
609+ goto out_unlock ;
610+ }
484611
485612 /*
486613 * Advance the write pointer, unless ordered zone append is in use. If
@@ -490,6 +617,7 @@ static int zloop_seq_write_prep(struct zloop_cmd *cmd)
490617 if (!is_append || !zlo -> ordered_zone_append ) {
491618 zone -> wp += nr_sectors ;
492619 if (zone -> wp == zone_end ) {
620+ zloop_lru_remove_open_zone (zlo , zone );
493621 zone -> cond = BLK_ZONE_COND_FULL ;
494622 zone -> wp = ULLONG_MAX ;
495623 }
@@ -746,6 +874,7 @@ static bool zloop_set_zone_append_sector(struct request *rq)
746874 rq -> __sector = zone -> wp ;
747875 zone -> wp += blk_rq_sectors (rq );
748876 if (zone -> wp >= zone_end ) {
877+ zloop_lru_remove_open_zone (zlo , zone );
749878 zone -> cond = BLK_ZONE_COND_FULL ;
750879 zone -> wp = ULLONG_MAX ;
751880 }
@@ -943,6 +1072,7 @@ static int zloop_init_zone(struct zloop_device *zlo, struct zloop_options *opts,
9431072 int ret ;
9441073
9451074 mutex_init (& zone -> lock );
1075+ INIT_LIST_HEAD (& zone -> open_zone_entry );
9461076 spin_lock_init (& zone -> wp_lock );
9471077 zone -> start = (sector_t )zone_no << zlo -> zone_shift ;
9481078
@@ -1063,12 +1193,20 @@ static int zloop_ctl_add(struct zloop_options *opts)
10631193 goto out ;
10641194 }
10651195
1196+ if (opts -> max_open_zones > nr_zones - opts -> nr_conv_zones ) {
1197+ pr_err ("Invalid maximum number of open zones %u\n" ,
1198+ opts -> max_open_zones );
1199+ goto out ;
1200+ }
1201+
10661202 zlo = kvzalloc_flex (* zlo , zones , nr_zones );
10671203 if (!zlo ) {
10681204 ret = - ENOMEM ;
10691205 goto out ;
10701206 }
10711207 WRITE_ONCE (zlo -> state , Zlo_creating );
1208+ spin_lock_init (& zlo -> open_zones_lock );
1209+ INIT_LIST_HEAD (& zlo -> open_zones_lru_list );
10721210
10731211 ret = mutex_lock_killable (& zloop_ctl_mutex );
10741212 if (ret )
@@ -1096,6 +1234,7 @@ static int zloop_ctl_add(struct zloop_options *opts)
10961234 zlo -> zone_capacity = zlo -> zone_size ;
10971235 zlo -> nr_zones = nr_zones ;
10981236 zlo -> nr_conv_zones = opts -> nr_conv_zones ;
1237+ zlo -> max_open_zones = opts -> max_open_zones ;
10991238 zlo -> buffered_io = opts -> buffered_io ;
11001239 zlo -> zone_append = opts -> zone_append ;
11011240 if (zlo -> zone_append )
@@ -1143,6 +1282,7 @@ static int zloop_ctl_add(struct zloop_options *opts)
11431282 lim .logical_block_size = zlo -> block_size ;
11441283 if (zlo -> zone_append )
11451284 lim .max_hw_zone_append_sectors = lim .max_hw_sectors ;
1285+ lim .max_open_zones = zlo -> max_open_zones ;
11461286
11471287 zlo -> tag_set .ops = & zloop_mq_ops ;
11481288 zlo -> tag_set .nr_hw_queues = opts -> nr_queues ;
@@ -1326,6 +1466,7 @@ static int zloop_parse_options(struct zloop_options *opts, const char *buf)
13261466 opts -> capacity = ZLOOP_DEF_ZONE_SIZE * ZLOOP_DEF_NR_ZONES ;
13271467 opts -> zone_size = ZLOOP_DEF_ZONE_SIZE ;
13281468 opts -> nr_conv_zones = ZLOOP_DEF_NR_CONV_ZONES ;
1469+ opts -> max_open_zones = ZLOOP_DEF_MAX_OPEN_ZONES ;
13291470 opts -> nr_queues = ZLOOP_DEF_NR_QUEUES ;
13301471 opts -> queue_depth = ZLOOP_DEF_QUEUE_DEPTH ;
13311472 opts -> buffered_io = ZLOOP_DEF_BUFFERED_IO ;
@@ -1404,6 +1545,13 @@ static int zloop_parse_options(struct zloop_options *opts, const char *buf)
14041545 }
14051546 opts -> nr_conv_zones = token ;
14061547 break ;
1548+ case ZLOOP_OPT_MAX_OPEN_ZONES :
1549+ if (match_uint (args , & token )) {
1550+ ret = - EINVAL ;
1551+ goto out ;
1552+ }
1553+ opts -> max_open_zones = token ;
1554+ break ;
14071555 case ZLOOP_OPT_BASE_DIR :
14081556 p = match_strdup (args );
14091557 if (!p ) {
0 commit comments