@@ -91,10 +91,12 @@ struct pstore_zone {
91
91
*
92
92
* @kpszs: kmsg dump storage zones
93
93
* @ppsz: pmsg storage zone
94
+ * @cpsz: console storage zone
94
95
* @kmsg_max_cnt: max count of @kpszs
95
96
* @kmsg_read_cnt: counter of total read kmsg dumps
96
97
* @kmsg_write_cnt: counter of total kmsg dump writes
97
98
* @pmsg_read_cnt: counter of total read pmsg zone
99
+ * @console_read_cnt: counter of total read console zone
98
100
* @oops_counter: counter of oops dumps
99
101
* @panic_counter: counter of panic dumps
100
102
* @recovered: whether finished recovering data from storage
@@ -106,10 +108,12 @@ struct pstore_zone {
106
108
struct psz_context {
107
109
struct pstore_zone * * kpszs ;
108
110
struct pstore_zone * ppsz ;
111
+ struct pstore_zone * cpsz ;
109
112
unsigned int kmsg_max_cnt ;
110
113
unsigned int kmsg_read_cnt ;
111
114
unsigned int kmsg_write_cnt ;
112
115
unsigned int pmsg_read_cnt ;
116
+ unsigned int console_read_cnt ;
113
117
/*
114
118
* These counters should be calculated during recovery.
115
119
* It records the oops/panic times after crashes rather than boots.
@@ -129,6 +133,9 @@ struct psz_context {
129
133
};
130
134
static struct psz_context pstore_zone_cxt ;
131
135
136
+ static void psz_flush_all_dirty_zones (struct work_struct * );
137
+ static DECLARE_DELAYED_WORK (psz_cleaner , psz_flush_all_dirty_zones ) ;
138
+
132
139
/**
133
140
* enum psz_flush_mode - flush mode for psz_zone_write()
134
141
*
@@ -237,6 +244,9 @@ static int psz_zone_write(struct pstore_zone *zone,
237
244
return 0 ;
238
245
dirty :
239
246
atomic_set (& zone -> dirty , true);
247
+ /* flush dirty zones nicely */
248
+ if (wcnt == - EBUSY && !is_on_panic ())
249
+ schedule_delayed_work (& psz_cleaner , msecs_to_jiffies (500 ));
240
250
return - EBUSY ;
241
251
}
242
252
@@ -293,6 +303,21 @@ static int psz_move_zone(struct pstore_zone *old, struct pstore_zone *new)
293
303
return 0 ;
294
304
}
295
305
306
+ static void psz_flush_all_dirty_zones (struct work_struct * work )
307
+ {
308
+ struct psz_context * cxt = & pstore_zone_cxt ;
309
+ int ret = 0 ;
310
+
311
+ if (cxt -> ppsz )
312
+ ret |= psz_flush_dirty_zone (cxt -> ppsz );
313
+ if (cxt -> cpsz )
314
+ ret |= psz_flush_dirty_zone (cxt -> cpsz );
315
+ if (cxt -> kpszs )
316
+ ret |= psz_flush_dirty_zones (cxt -> kpszs , cxt -> kmsg_max_cnt );
317
+ if (ret && cxt -> pstore_zone_info )
318
+ schedule_delayed_work (& psz_cleaner , msecs_to_jiffies (1000 ));
319
+ }
320
+
296
321
static int psz_kmsg_recover_data (struct psz_context * cxt )
297
322
{
298
323
struct pstore_zone_info * info = cxt -> pstore_zone_info ;
@@ -545,6 +570,10 @@ static inline int psz_recovery(struct psz_context *cxt)
545
570
goto out ;
546
571
547
572
ret = psz_recover_zone (cxt , cxt -> ppsz );
573
+ if (ret )
574
+ goto out ;
575
+
576
+ ret = psz_recover_zone (cxt , cxt -> cpsz );
548
577
549
578
out :
550
579
if (unlikely (ret ))
@@ -562,6 +591,7 @@ static int psz_pstore_open(struct pstore_info *psi)
562
591
563
592
cxt -> kmsg_read_cnt = 0 ;
564
593
cxt -> pmsg_read_cnt = 0 ;
594
+ cxt -> console_read_cnt = 0 ;
565
595
return 0 ;
566
596
}
567
597
@@ -626,8 +656,9 @@ static int psz_pstore_erase(struct pstore_record *record)
626
656
return psz_kmsg_erase (cxt , cxt -> kpszs [record -> id ], record );
627
657
case PSTORE_TYPE_PMSG :
628
658
return psz_record_erase (cxt , cxt -> ppsz );
629
- default :
630
- return - EINVAL ;
659
+ case PSTORE_TYPE_CONSOLE :
660
+ return psz_record_erase (cxt , cxt -> cpsz );
661
+ default : return - EINVAL ;
631
662
}
632
663
}
633
664
@@ -690,9 +721,10 @@ static int notrace psz_kmsg_write(struct psz_context *cxt,
690
721
return - ENOSPC ;
691
722
692
723
ret = psz_kmsg_write_record (cxt , record );
693
- if (!ret ) {
724
+ if (!ret && is_on_panic ()) {
725
+ /* ensure all data are flushed to storage when panic */
694
726
pr_debug ("try to flush other dirty zones\n" );
695
- psz_flush_dirty_zones ( cxt -> kpszs , cxt -> kmsg_max_cnt );
727
+ psz_flush_all_dirty_zones ( NULL );
696
728
}
697
729
698
730
/* always return 0 as we had handled it on buffer */
@@ -756,9 +788,18 @@ static int notrace psz_pstore_write(struct pstore_record *record)
756
788
record -> reason == KMSG_DUMP_PANIC )
757
789
atomic_set (& cxt -> on_panic , 1 );
758
790
791
+ /*
792
+ * if on panic, do not write except panic records
793
+ * Fix case that panic_write prints log which wakes up console backend.
794
+ */
795
+ if (is_on_panic () && record -> type != PSTORE_TYPE_DMESG )
796
+ return - EBUSY ;
797
+
759
798
switch (record -> type ) {
760
799
case PSTORE_TYPE_DMESG :
761
800
return psz_kmsg_write (cxt , record );
801
+ case PSTORE_TYPE_CONSOLE :
802
+ return psz_record_write (cxt -> cpsz , record );
762
803
case PSTORE_TYPE_PMSG :
763
804
return psz_record_write (cxt -> ppsz , record );
764
805
default :
@@ -783,6 +824,13 @@ static struct pstore_zone *psz_read_next_zone(struct psz_context *cxt)
783
824
return zone ;
784
825
}
785
826
827
+ if (cxt -> console_read_cnt == 0 ) {
828
+ cxt -> console_read_cnt ++ ;
829
+ zone = cxt -> cpsz ;
830
+ if (psz_old_ok (zone ))
831
+ return zone ;
832
+ }
833
+
786
834
return NULL ;
787
835
}
788
836
@@ -893,6 +941,8 @@ static ssize_t psz_pstore_read(struct pstore_record *record)
893
941
readop = psz_kmsg_read ;
894
942
record -> id = cxt -> kmsg_read_cnt - 1 ;
895
943
break ;
944
+ case PSTORE_TYPE_CONSOLE :
945
+ fallthrough ;
896
946
case PSTORE_TYPE_PMSG :
897
947
readop = psz_record_read ;
898
948
break ;
@@ -953,6 +1003,8 @@ static void psz_free_all_zones(struct psz_context *cxt)
953
1003
psz_free_zones (& cxt -> kpszs , & cxt -> kmsg_max_cnt );
954
1004
if (cxt -> ppsz )
955
1005
psz_free_zone (& cxt -> ppsz );
1006
+ if (cxt -> cpsz )
1007
+ psz_free_zone (& cxt -> cpsz );
956
1008
}
957
1009
958
1010
static struct pstore_zone * psz_init_zone (enum pstore_type_id type ,
@@ -1054,6 +1106,15 @@ static int psz_alloc_zones(struct psz_context *cxt)
1054
1106
goto free_out ;
1055
1107
}
1056
1108
1109
+ off_size += info -> console_size ;
1110
+ cxt -> cpsz = psz_init_zone (PSTORE_TYPE_CONSOLE , & off ,
1111
+ info -> console_size );
1112
+ if (IS_ERR (cxt -> cpsz )) {
1113
+ err = PTR_ERR (cxt -> cpsz );
1114
+ cxt -> cpsz = NULL ;
1115
+ goto free_out ;
1116
+ }
1117
+
1057
1118
cxt -> kpszs = psz_init_zones (PSTORE_TYPE_DMESG , & off ,
1058
1119
info -> total_size - off_size ,
1059
1120
info -> kmsg_size , & cxt -> kmsg_max_cnt );
@@ -1088,7 +1149,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
1088
1149
return - EINVAL ;
1089
1150
}
1090
1151
1091
- if (!info -> kmsg_size && !info -> pmsg_size ) {
1152
+ if (!info -> kmsg_size && !info -> pmsg_size && ! info -> console_size ) {
1092
1153
pr_warn ("at least one record size must be non-zero\n" );
1093
1154
return - EINVAL ;
1094
1155
}
@@ -1111,6 +1172,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
1111
1172
check_size (total_size , 4096 );
1112
1173
check_size (kmsg_size , SECTOR_SIZE );
1113
1174
check_size (pmsg_size , SECTOR_SIZE );
1175
+ check_size (console_size , SECTOR_SIZE );
1114
1176
1115
1177
#undef check_size
1116
1178
@@ -1137,6 +1199,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
1137
1199
pr_debug ("\ttotal size : %ld Bytes\n" , info -> total_size );
1138
1200
pr_debug ("\tkmsg size : %ld Bytes\n" , info -> kmsg_size );
1139
1201
pr_debug ("\tpmsg size : %ld Bytes\n" , info -> pmsg_size );
1202
+ pr_debug ("\tconsole size : %ld Bytes\n" , info -> console_size );
1140
1203
1141
1204
err = psz_alloc_zones (cxt );
1142
1205
if (err ) {
@@ -1170,6 +1233,10 @@ int register_pstore_zone(struct pstore_zone_info *info)
1170
1233
cxt -> pstore .flags |= PSTORE_FLAGS_PMSG ;
1171
1234
pr_cont (" pmsg" );
1172
1235
}
1236
+ if (info -> console_size ) {
1237
+ cxt -> pstore .flags |= PSTORE_FLAGS_CONSOLE ;
1238
+ pr_cont (" console" );
1239
+ }
1173
1240
pr_cont ("\n" );
1174
1241
1175
1242
err = pstore_register (& cxt -> pstore );
@@ -1211,6 +1278,10 @@ void unregister_pstore_zone(struct pstore_zone_info *info)
1211
1278
/* Stop incoming writes from pstore. */
1212
1279
pstore_unregister (& cxt -> pstore );
1213
1280
1281
+ /* Flush any pending writes. */
1282
+ psz_flush_all_dirty_zones (NULL );
1283
+ flush_delayed_work (& psz_cleaner );
1284
+
1214
1285
/* Clean up allocations. */
1215
1286
kfree (cxt -> pstore .buf );
1216
1287
cxt -> pstore .buf = NULL ;
0 commit comments