@@ -167,6 +167,124 @@ static int zns_get_wcidx(struct zns_ssd* zns)
167167 return -1 ;
168168}
169169
170+ static void zns_invalidate_zone_cache (struct zns_ssd * zns , uint32_t zone_idx )
171+ {
172+ int i ;
173+
174+ for (i = 0 ; i < zns -> cache .num_wc ; i ++ ) {
175+ if (zns -> cache .write_cache [i ].sblk == zone_idx ) {
176+ #ifdef FEMU_DEBUG_ZFTL
177+ uint64_t discarded_entries = zns -> cache .write_cache [i ].used ;
178+ #endif
179+
180+ zns -> cache .write_cache [i ].used = 0 ;
181+ zns -> cache .write_cache [i ].sblk = INVALID_SBLK ;
182+
183+ ftl_debug ("Invalidated write_cache[%d] for zone %u (%lu entries discarded)\n" ,
184+ i , zone_idx , discarded_entries );
185+ return ;
186+ }
187+ }
188+ }
189+
190+ static void zns_invalidate_zone_mappings (struct zns_ssd * zns , uint32_t zone_idx ,
191+ uint64_t zone_size_lbas , uint64_t lbasz )
192+ {
193+ uint64_t zone_start_lba = zone_idx * zone_size_lbas ;
194+ uint64_t zone_end_lba = (zone_idx + 1 ) * zone_size_lbas ;
195+ uint64_t secs_per_pg = LOGICAL_PAGE_SIZE / lbasz ;
196+ uint64_t start_lpn = zone_start_lba / secs_per_pg ;
197+ uint64_t end_lpn = zone_end_lba / secs_per_pg ;
198+ uint64_t lpn ;
199+ uint64_t invalidated_count = 0 ;
200+
201+ for (lpn = start_lpn ; lpn < end_lpn && lpn < zns -> l2p_sz ; lpn ++ ) {
202+ if (zns -> maptbl [lpn ].ppa != UNMAPPED_PPA ) {
203+ zns -> maptbl [lpn ].ppa = UNMAPPED_PPA ;
204+ invalidated_count ++ ;
205+ }
206+ }
207+
208+ ftl_debug ("Invalidated %lu LPN mappings for zone %u (LPN %lu-%lu)\n" ,
209+ invalidated_count , zone_idx , start_lpn , end_lpn - 1 );
210+ }
211+
212+ static void zns_reset_block_state (struct zns_ssd * zns , uint32_t zone_idx )
213+ {
214+ int ch , lun , pl ;
215+ struct ppa ppa ;
216+ struct zns_blk * blk ;
217+
218+ for (ch = 0 ; ch < zns -> num_ch ; ch ++ ) {
219+ for (lun = 0 ; lun < zns -> num_lun ; lun ++ ) {
220+ for (pl = 0 ; pl < zns -> num_plane ; pl ++ ) {
221+ ppa .g .ch = ch ;
222+ ppa .g .fc = lun ;
223+ ppa .g .pl = pl ;
224+ ppa .g .blk = zone_idx ;
225+ ppa .g .pg = 0 ;
226+ ppa .g .spg = 0 ;
227+
228+ blk = get_blk (zns , & ppa );
229+ blk -> page_wp = 0 ;
230+ }
231+ }
232+ }
233+
234+ ftl_debug ("Reset block state for zone %u (all page_wp = 0)\n" , zone_idx );
235+ }
236+
237+ uint64_t zns_zone_reset (struct zns_ssd * zns , uint32_t zone_idx ,
238+ uint64_t zone_size_lbas , uint64_t lbasz , uint64_t stime )
239+ {
240+ int ch , lun , pl ;
241+ struct ppa ppa ;
242+ struct nand_cmd erase_cmd ;
243+ uint64_t sublat , maxlat = 0 ;
244+ uint64_t total_blocks_erased = 0 ;
245+
246+ ftl_debug ("=== Zone Reset Started for Zone %u ===\n" , zone_idx );
247+
248+ /* Step 1: Invalidate write cache (instant) */
249+ zns_invalidate_zone_cache (zns , zone_idx );
250+
251+ /* Step 2: Invalidate L2P mappings (instant) */
252+ zns_invalidate_zone_mappings (zns , zone_idx , zone_size_lbas , lbasz );
253+
254+ /* Step 3: Reset block state (instant) */
255+ zns_reset_block_state (zns , zone_idx );
256+
257+ /* Step 4: Simulate physical erase across all channels/LUNs/planes (parallel) */
258+ erase_cmd .type = USER_IO ;
259+ erase_cmd .cmd = NAND_ERASE ;
260+ erase_cmd .stime = stime ;
261+
262+ for (ch = 0 ; ch < zns -> num_ch ; ch ++ ) {
263+ for (lun = 0 ; lun < zns -> num_lun ; lun ++ ) {
264+ for (pl = 0 ; pl < zns -> num_plane ; pl ++ ) {
265+ ppa .ppa = 0 ;
266+ ppa .g .ch = ch ;
267+ ppa .g .fc = lun ;
268+ ppa .g .pl = pl ;
269+ ppa .g .blk = zone_idx ;
270+ ppa .g .pg = 0 ;
271+ ppa .g .spg = 0 ;
272+
273+ sublat = zns_advance_status (zns , & ppa , & erase_cmd );
274+ maxlat = (sublat > maxlat ) ? sublat : maxlat ;
275+ total_blocks_erased ++ ;
276+ }
277+ }
278+ }
279+
280+ ftl_debug ("Zone %u reset complete: erased %lu blocks across %d ch * %d lun * %d planes\n" ,
281+ zone_idx , total_blocks_erased , (int )zns -> num_ch , (int )zns -> num_lun , (int )zns -> num_plane );
282+ ftl_debug ("Maximum erase latency: %lu ns (%.2f ms)\n" , maxlat , maxlat / 1000000.0 );
283+ ftl_debug ("=== Zone Reset Finished ===\n\n" );
284+
285+ return maxlat ;
286+ }
287+
170288static uint64_t zns_read (struct zns_ssd * zns , NvmeRequest * req )
171289{
172290 uint64_t lba = req -> slba ;
@@ -192,7 +310,7 @@ static uint64_t zns_read(struct zns_ssd *zns, NvmeRequest *req)
192310 srd .stime = req -> stime ;
193311
194312 sublat = zns_advance_status (zns , & ppa , & srd );
195- femu_log ("[R] lpn:\t%lu\t<--ch:\t%u\tlun:\t%u\tpl:\t%u\tblk:\t%u\tpg:\t%u\tsubpg:\t%u\tlat\t%lu\n" ,lpn ,ppa .g .ch ,ppa .g .fc ,ppa .g .pl ,ppa .g .blk ,ppa .g .pg ,ppa .g .spg ,sublat );
313+ ftl_debug ("[R] lpn:\t%lu\t<--ch:\t%u\tlun:\t%u\tpl:\t%u\tblk:\t%u\tpg:\t%u\tsubpg:\t%u\tlat\t%lu\n" ,lpn ,ppa .g .ch ,ppa .g .fc ,ppa .g .pl ,ppa .g .blk ,ppa .g .pg ,ppa .g .spg ,sublat );
196314 maxlat = (sublat > maxlat ) ? sublat : maxlat ;
197315 }
198316
@@ -234,7 +352,7 @@ static uint64_t zns_wc_flush(struct zns_ssd* zns, int wcidx, int type,uint64_t s
234352 ppa .g .spg = subpage ;
235353 /* update maptbl */
236354 set_maptbl_ent (zns , lpn , & ppa );
237- //femu_log ("[F] lpn:\t%lu\t-->ch:\t%u\tlun:\t%u\tpl:\t%u\tblk:\t%u\tpg:\t%u\tsubpg:\t%u\tlat\t%lu\n",lpn,ppa.g.ch,ppa.g.fc,ppa.g.pl,ppa.g.blk,ppa.g.pg,ppa.g.spg,sublat);
355+ // ftl_debug ("[F] lpn:\t%lu\t-->ch:\t%u\tlun:\t%u\tpl:\t%u\tblk:\t%u\tpg:\t%u\tsubpg:\t%u\tlat\t%lu\n",lpn,ppa.g.ch,ppa.g.fc,ppa.g.pl,ppa.g.blk,ppa.g.pg,ppa.g.spg,sublat);
238356 }
239357 i += ZNS_PAGE_SIZE /LOGICAL_PAGE_SIZE ;
240358 }
@@ -295,16 +413,16 @@ static uint64_t zns_write(struct zns_ssd *zns, NvmeRequest *req)
295413 for (lpn = start_lpn ; lpn <= end_lpn ; lpn ++ ) {
296414 if (zns -> cache .write_cache [wcidx ].used == zns -> cache .write_cache [wcidx ].cap )
297415 {
298- femu_log ("[W] flush wc %d (%u/%u)\n" ,wcidx ,(int )zns -> cache .write_cache [wcidx ].used ,(int )zns -> cache .write_cache [wcidx ].cap );
416+ ftl_debug ("[W] flush wc %d (%u/%u)\n" ,wcidx ,(int )zns -> cache .write_cache [wcidx ].used ,(int )zns -> cache .write_cache [wcidx ].cap );
299417 sublat = zns_wc_flush (zns ,wcidx ,USER_IO ,req -> stime );
300- femu_log ("[W] flush lat: %u\n" , (int )sublat );
418+ ftl_debug ("[W] flush lat: %u\n" , (int )sublat );
301419 maxlat = (sublat > maxlat ) ? sublat : maxlat ;
302420 sublat = 0 ;
303421 }
304422 zns -> cache .write_cache [wcidx ].lpns [zns -> cache .write_cache [wcidx ].used ++ ]= lpn ;
305423 sublat += SRAM_WRITE_LATENCY_NS ; //Simplified timing emulation
306424 maxlat = (sublat > maxlat ) ? sublat : maxlat ;
307- femu_log ("[W] lpn:\t%lu\t-->wc cache:%u, used:%u\n" ,lpn ,(int )wcidx ,(int )zns -> cache .write_cache [wcidx ].used );
425+ ftl_debug ("[W] lpn:\t%lu\t-->wc cache:%u, used:%u\n" ,lpn ,(int )wcidx ,(int )zns -> cache .write_cache [wcidx ].used );
308426 }
309427 return maxlat ;
310428}
0 commit comments