@@ -327,8 +327,10 @@ void bch2_journal_reclaim_fast(struct journal *j)
327
327
popped = true;
328
328
}
329
329
330
- if (popped )
330
+ if (popped ) {
331
331
bch2_journal_space_available (j );
332
+ __closure_wake_up (& j -> reclaim_flush_wait );
333
+ }
332
334
}
333
335
334
336
bool __bch2_journal_pin_put (struct journal * j , u64 seq )
@@ -362,6 +364,9 @@ static inline bool __journal_pin_drop(struct journal *j,
362
364
pin -> seq = 0 ;
363
365
list_del_init (& pin -> list );
364
366
367
+ if (j -> reclaim_flush_wait .list .first )
368
+ __closure_wake_up (& j -> reclaim_flush_wait );
369
+
365
370
/*
366
371
* Unpinning a journal entry may make journal_next_bucket() succeed, if
367
372
* writing a new last_seq will now make another bucket available:
@@ -383,11 +388,11 @@ static enum journal_pin_type journal_pin_type(journal_pin_flush_fn fn)
383
388
{
384
389
if (fn == bch2_btree_node_flush0 ||
385
390
fn == bch2_btree_node_flush1 )
386
- return JOURNAL_PIN_btree ;
391
+ return JOURNAL_PIN_TYPE_btree ;
387
392
else if (fn == bch2_btree_key_cache_journal_flush )
388
- return JOURNAL_PIN_key_cache ;
393
+ return JOURNAL_PIN_TYPE_key_cache ;
389
394
else
390
- return JOURNAL_PIN_other ;
395
+ return JOURNAL_PIN_TYPE_other ;
391
396
}
392
397
393
398
static inline void bch2_journal_pin_set_locked (struct journal * j , u64 seq ,
@@ -406,7 +411,12 @@ static inline void bch2_journal_pin_set_locked(struct journal *j, u64 seq,
406
411
atomic_inc (& pin_list -> count );
407
412
pin -> seq = seq ;
408
413
pin -> flush = flush_fn ;
409
- list_add (& pin -> list , & pin_list -> list [type ]);
414
+
415
+ if (list_empty (& pin_list -> unflushed [type ]) &&
416
+ j -> reclaim_flush_wait .list .first )
417
+ __closure_wake_up (& j -> reclaim_flush_wait );
418
+
419
+ list_add (& pin -> list , & pin_list -> unflushed [type ]);
410
420
}
411
421
412
422
void bch2_journal_pin_copy (struct journal * j ,
@@ -499,16 +509,15 @@ journal_get_next_pin(struct journal *j,
499
509
{
500
510
struct journal_entry_pin_list * pin_list ;
501
511
struct journal_entry_pin * ret = NULL ;
502
- unsigned i ;
503
512
504
513
fifo_for_each_entry_ptr (pin_list , & j -> pin , * seq ) {
505
514
if (* seq > seq_to_flush && !allowed_above_seq )
506
515
break ;
507
516
508
- for (i = 0 ; i < JOURNAL_PIN_NR ; i ++ )
509
- if (((( 1U << i ) & allowed_below_seq ) && * seq <= seq_to_flush ) ||
510
- (( 1U << i ) & allowed_above_seq )) {
511
- ret = list_first_entry_or_null (& pin_list -> list [i ],
517
+ for (unsigned i = 0 ; i < JOURNAL_PIN_TYPE_NR ; i ++ )
518
+ if (((BIT ( i ) & allowed_below_seq ) && * seq <= seq_to_flush ) ||
519
+ (BIT ( i ) & allowed_above_seq )) {
520
+ ret = list_first_entry_or_null (& pin_list -> unflushed [i ],
512
521
struct journal_entry_pin , list );
513
522
if (ret )
514
523
return ret ;
@@ -544,16 +553,18 @@ static size_t journal_flush_pins(struct journal *j,
544
553
}
545
554
546
555
if (min_key_cache ) {
547
- allowed_above |= 1U << JOURNAL_PIN_key_cache ;
548
- allowed_below |= 1U << JOURNAL_PIN_key_cache ;
556
+ allowed_above |= BIT ( JOURNAL_PIN_TYPE_key_cache ) ;
557
+ allowed_below |= BIT ( JOURNAL_PIN_TYPE_key_cache ) ;
549
558
}
550
559
551
560
cond_resched ();
552
561
553
562
j -> last_flushed = jiffies ;
554
563
555
564
spin_lock (& j -> lock );
556
- pin = journal_get_next_pin (j , seq_to_flush , allowed_below , allowed_above , & seq );
565
+ pin = journal_get_next_pin (j , seq_to_flush ,
566
+ allowed_below ,
567
+ allowed_above , & seq );
557
568
if (pin ) {
558
569
BUG_ON (j -> flush_in_progress );
559
570
j -> flush_in_progress = pin ;
@@ -576,7 +587,7 @@ static size_t journal_flush_pins(struct journal *j,
576
587
spin_lock (& j -> lock );
577
588
/* Pin might have been dropped or rearmed: */
578
589
if (likely (!err && !j -> flush_in_progress_dropped ))
579
- list_move (& pin -> list , & journal_seq_pin (j , seq )-> flushed );
590
+ list_move (& pin -> list , & journal_seq_pin (j , seq )-> flushed [ journal_pin_type ( flush_fn )] );
580
591
j -> flush_in_progress = NULL ;
581
592
j -> flush_in_progress_dropped = false;
582
593
spin_unlock (& j -> lock );
@@ -816,23 +827,60 @@ int bch2_journal_reclaim_start(struct journal *j)
816
827
return 0 ;
817
828
}
818
829
830
+ static bool journal_pins_still_flushing (struct journal * j , u64 seq_to_flush ,
831
+ unsigned types )
832
+ {
833
+ struct journal_entry_pin_list * pin_list ;
834
+ u64 seq ;
835
+
836
+ spin_lock (& j -> lock );
837
+ fifo_for_each_entry_ptr (pin_list , & j -> pin , seq ) {
838
+ if (seq > seq_to_flush )
839
+ break ;
840
+
841
+ for (unsigned i = 0 ; i < JOURNAL_PIN_TYPE_NR ; i ++ )
842
+ if ((BIT (i ) & types ) &&
843
+ (!list_empty (& pin_list -> unflushed [i ]) ||
844
+ !list_empty (& pin_list -> flushed [i ]))) {
845
+ spin_unlock (& j -> lock );
846
+ return true;
847
+ }
848
+ }
849
+ spin_unlock (& j -> lock );
850
+
851
+ return false;
852
+ }
853
+
854
+ static bool journal_flush_pins_or_still_flushing (struct journal * j , u64 seq_to_flush ,
855
+ unsigned types )
856
+ {
857
+ return journal_flush_pins (j , seq_to_flush , types , 0 , 0 , 0 ) ||
858
+ journal_pins_still_flushing (j , seq_to_flush , types );
859
+ }
860
+
819
861
static int journal_flush_done (struct journal * j , u64 seq_to_flush ,
820
862
bool * did_work )
821
863
{
822
- int ret ;
864
+ int ret = 0 ;
823
865
824
866
ret = bch2_journal_error (j );
825
867
if (ret )
826
868
return ret ;
827
869
828
870
mutex_lock (& j -> reclaim_lock );
829
871
830
- if (journal_flush_pins (j , seq_to_flush ,
831
- (1U << JOURNAL_PIN_key_cache )|
832
- (1U << JOURNAL_PIN_other ), 0 , 0 , 0 ) ||
833
- journal_flush_pins (j , seq_to_flush ,
834
- (1U << JOURNAL_PIN_btree ), 0 , 0 , 0 ))
872
+ if (journal_flush_pins_or_still_flushing (j , seq_to_flush ,
873
+ BIT (JOURNAL_PIN_TYPE_key_cache )|
874
+ BIT (JOURNAL_PIN_TYPE_other ))) {
875
+ * did_work = true;
876
+ goto unlock ;
877
+ }
878
+
879
+ if (journal_flush_pins_or_still_flushing (j , seq_to_flush ,
880
+ BIT (JOURNAL_PIN_TYPE_btree ))) {
835
881
* did_work = true;
882
+ goto unlock ;
883
+ }
836
884
837
885
if (seq_to_flush > journal_cur_seq (j ))
838
886
bch2_journal_entry_close (j );
@@ -847,6 +895,7 @@ static int journal_flush_done(struct journal *j, u64 seq_to_flush,
847
895
!fifo_used (& j -> pin );
848
896
849
897
spin_unlock (& j -> lock );
898
+ unlock :
850
899
mutex_unlock (& j -> reclaim_lock );
851
900
852
901
return ret ;
@@ -860,7 +909,7 @@ bool bch2_journal_flush_pins(struct journal *j, u64 seq_to_flush)
860
909
if (!test_bit (JOURNAL_running , & j -> flags ))
861
910
return false;
862
911
863
- closure_wait_event (& j -> async_wait ,
912
+ closure_wait_event (& j -> reclaim_flush_wait ,
864
913
journal_flush_done (j , seq_to_flush , & did_work ));
865
914
866
915
return did_work ;
@@ -926,3 +975,54 @@ int bch2_journal_flush_device_pins(struct journal *j, int dev_idx)
926
975
927
976
return ret ;
928
977
}
978
+
979
+ bool bch2_journal_seq_pins_to_text (struct printbuf * out , struct journal * j , u64 * seq )
980
+ {
981
+ struct journal_entry_pin_list * pin_list ;
982
+ struct journal_entry_pin * pin ;
983
+
984
+ spin_lock (& j -> lock );
985
+ if (!test_bit (JOURNAL_running , & j -> flags )) {
986
+ spin_unlock (& j -> lock );
987
+ return true;
988
+ }
989
+
990
+ * seq = max (* seq , j -> pin .front );
991
+
992
+ if (* seq >= j -> pin .back ) {
993
+ spin_unlock (& j -> lock );
994
+ return true;
995
+ }
996
+
997
+ out -> atomic ++ ;
998
+
999
+ pin_list = journal_seq_pin (j , * seq );
1000
+
1001
+ prt_printf (out , "%llu: count %u\n" , * seq , atomic_read (& pin_list -> count ));
1002
+ printbuf_indent_add (out , 2 );
1003
+
1004
+ prt_printf (out , "unflushed:\n" );
1005
+ for (unsigned i = 0 ; i < ARRAY_SIZE (pin_list -> unflushed ); i ++ )
1006
+ list_for_each_entry (pin , & pin_list -> unflushed [i ], list )
1007
+ prt_printf (out , "\t%px %ps\n" , pin , pin -> flush );
1008
+
1009
+ prt_printf (out , "flushed:\n" );
1010
+ for (unsigned i = 0 ; i < ARRAY_SIZE (pin_list -> flushed ); i ++ )
1011
+ list_for_each_entry (pin , & pin_list -> flushed [i ], list )
1012
+ prt_printf (out , "\t%px %ps\n" , pin , pin -> flush );
1013
+
1014
+ printbuf_indent_sub (out , 2 );
1015
+
1016
+ -- out -> atomic ;
1017
+ spin_unlock (& j -> lock );
1018
+
1019
+ return false;
1020
+ }
1021
+
1022
+ void bch2_journal_pins_to_text (struct printbuf * out , struct journal * j )
1023
+ {
1024
+ u64 seq = 0 ;
1025
+
1026
+ while (!bch2_journal_seq_pins_to_text (out , j , & seq ))
1027
+ seq ++ ;
1028
+ }
0 commit comments