• Home
  • Raw
  • Download

Lines Matching full:zone

26  * struct psz_head - header of zone to flush to storage
31 * @data: zone data.
66 * @off: zone offset of storage
67 * @type: front-end type for this zone
68 * @name: front-end name for this zone
69 * @buffer: pointer to data buffer managed by this zone
72 * @should_recover: whether this zone should recover from storage
75 * zone structure in memory.
90 * struct psz_context - all about running state of pstore/zone
93 * @ppsz: pmsg storage zone
94 * @cpsz: console storage zone
96 * @bpsz: blackbox storage zone
100 * @pmsg_read_cnt: counter of total read pmsg zone
101 * @console_read_cnt: counter of total read console zone
103 * @ftrace_read_cnt: counter of max read ftrace zone
104 * @blackbox_read_cnt: counter of total read blackbox zone
154 * @FLUSH_META: just flush meta data of zone to storage
155 * @FLUSH_ALL: flush all of zone
164 static inline int buffer_datalen(struct pstore_zone *zone) in buffer_datalen() argument
166 return atomic_read(&zone->buffer->datalen); in buffer_datalen()
169 static inline int buffer_start(struct pstore_zone *zone) in buffer_start() argument
171 return atomic_read(&zone->buffer->start); in buffer_start()
179 static ssize_t psz_zone_read_buffer(struct pstore_zone *zone, char *buf, in psz_zone_read_buffer() argument
182 if (!buf || !zone || !zone->buffer) in psz_zone_read_buffer()
184 if (off > zone->buffer_size) in psz_zone_read_buffer()
186 len = min_t(size_t, len, zone->buffer_size - off); in psz_zone_read_buffer()
187 memcpy(buf, zone->buffer->data + off, len); in psz_zone_read_buffer()
191 static int psz_zone_read_oldbuf(struct pstore_zone *zone, char *buf, in psz_zone_read_oldbuf() argument
194 if (!buf || !zone || !zone->oldbuf) in psz_zone_read_oldbuf()
196 if (off > zone->buffer_size) in psz_zone_read_oldbuf()
198 len = min_t(size_t, len, zone->buffer_size - off); in psz_zone_read_oldbuf()
199 memcpy(buf, zone->oldbuf->data + off, len); in psz_zone_read_oldbuf()
203 static int psz_zone_write(struct pstore_zone *zone, in psz_zone_write() argument
212 if (off > zone->buffer_size) in psz_zone_write()
215 wlen = min_t(size_t, len, zone->buffer_size - off); in psz_zone_write()
217 memcpy(zone->buffer->data + off, buf, wlen); in psz_zone_write()
218 atomic_set(&zone->buffer->datalen, wlen + off); in psz_zone_write()
235 wcnt = writeop((const char *)zone->buffer->data + off, wlen, in psz_zone_write()
236 zone->off + sizeof(*zone->buffer) + off); in psz_zone_write()
242 wcnt = writeop((const char *)zone->buffer, wlen, zone->off); in psz_zone_write()
247 wlen = zone->buffer_size + sizeof(*zone->buffer); in psz_zone_write()
248 wcnt = writeop((const char *)zone->buffer, wlen, zone->off); in psz_zone_write()
256 /* no need to mark dirty if going to try next zone */ in psz_zone_write()
259 atomic_set(&zone->dirty, true); in psz_zone_write()
266 static int psz_flush_dirty_zone(struct pstore_zone *zone) in psz_flush_dirty_zone() argument
270 if (unlikely(!zone)) in psz_flush_dirty_zone()
276 if (!atomic_xchg(&zone->dirty, false)) in psz_flush_dirty_zone()
279 ret = psz_zone_write(zone, FLUSH_ALL, NULL, 0, 0); in psz_flush_dirty_zone()
281 atomic_set(&zone->dirty, true); in psz_flush_dirty_zone()
288 struct pstore_zone *zone; in psz_flush_dirty_zones() local
294 zone = zones[i]; in psz_flush_dirty_zones()
295 if (!zone) in psz_flush_dirty_zones()
297 ret = psz_flush_dirty_zone(zone); in psz_flush_dirty_zones()
341 struct pstore_zone *zone = NULL; in psz_kmsg_recover_data() local
350 zone = cxt->kpszs[i]; in psz_kmsg_recover_data()
351 if (unlikely(!zone)) in psz_kmsg_recover_data()
353 if (atomic_read(&zone->dirty)) { in psz_kmsg_recover_data()
358 ret = psz_move_zone(zone, new); in psz_kmsg_recover_data()
360 pr_err("move zone from %lu to %d failed\n", in psz_kmsg_recover_data()
366 if (!zone->should_recover) in psz_kmsg_recover_data()
368 buf = zone->buffer; in psz_kmsg_recover_data()
369 rcnt = info->read((char *)buf, zone->buffer_size + sizeof(*buf), in psz_kmsg_recover_data()
370 zone->off); in psz_kmsg_recover_data()
371 if (rcnt != zone->buffer_size + sizeof(*buf)) in psz_kmsg_recover_data()
380 struct pstore_zone *zone; in psz_kmsg_recover_meta() local
398 zone = cxt->kpszs[i]; in psz_kmsg_recover_meta()
399 if (unlikely(!zone)) in psz_kmsg_recover_meta()
402 rcnt = info->read((char *)buf, len, zone->off); in psz_kmsg_recover_meta()
405 zone->name, i); in psz_kmsg_recover_meta()
408 pr_err("read %s with id %lu failed\n", zone->name, i); in psz_kmsg_recover_meta()
412 if (buf->sig != zone->buffer->sig) { in psz_kmsg_recover_meta()
413 pr_debug("no valid data in kmsg dump zone %lu\n", i); in psz_kmsg_recover_meta()
417 if (zone->buffer_size < atomic_read(&buf->datalen)) { in psz_kmsg_recover_meta()
418 pr_info("found overtop zone: %s: id %lu, off %lld, size %zu\n", in psz_kmsg_recover_meta()
419 zone->name, i, zone->off, in psz_kmsg_recover_meta()
420 zone->buffer_size); in psz_kmsg_recover_meta()
426 pr_info("found invalid zone: %s: id %lu, off %lld, size %zu\n", in psz_kmsg_recover_meta()
427 zone->name, i, zone->off, in psz_kmsg_recover_meta()
428 zone->buffer_size); in psz_kmsg_recover_meta()
433 * we get the newest zone, and the next one must be the oldest in psz_kmsg_recover_meta()
434 * or unused zone, because we do write one by one like a circle. in psz_kmsg_recover_meta()
449 pr_debug("found erased zone: %s: id %lu, off %lld, size %zu, datalen %d\n", in psz_kmsg_recover_meta()
450 zone->name, i, zone->off, in psz_kmsg_recover_meta()
451 zone->buffer_size, in psz_kmsg_recover_meta()
457 zone->should_recover = true; in psz_kmsg_recover_meta()
458 pr_debug("found nice zone: %s: id %lu, off %lld, size %zu, datalen %d\n", in psz_kmsg_recover_meta()
459 zone->name, i, zone->off, in psz_kmsg_recover_meta()
460 zone->buffer_size, atomic_read(&buf->datalen)); in psz_kmsg_recover_meta()
487 static int psz_recover_zone(struct psz_context *cxt, struct pstore_zone *zone) in psz_recover_zone() argument
495 if (!zone || zone->oldbuf) in psz_recover_zone()
500 psz_flush_dirty_zone(zone); in psz_recover_zone()
508 rcnt = info->read((char *)&tmpbuf, len, zone->off); in psz_recover_zone()
510 pr_debug("read zone %s failed\n", zone->name); in psz_recover_zone()
514 if (tmpbuf.sig != zone->buffer->sig) { in psz_recover_zone()
515 pr_debug("no valid data in zone %s\n", zone->name); in psz_recover_zone()
519 if (zone->buffer_size < atomic_read(&tmpbuf.datalen) || in psz_recover_zone()
520 zone->buffer_size < atomic_read(&tmpbuf.start)) { in psz_recover_zone()
521 pr_info("found overtop zone: %s: off %lld, size %zu\n", in psz_recover_zone()
522 zone->name, zone->off, zone->buffer_size); in psz_recover_zone()
528 pr_debug("found erased zone: %s: off %lld, size %zu, datalen %d\n", in psz_recover_zone()
529 zone->name, zone->off, zone->buffer_size, in psz_recover_zone()
534 pr_debug("found nice zone: %s: off %lld, size %zu, datalen %d\n", in psz_recover_zone()
535 zone->name, zone->off, zone->buffer_size, in psz_recover_zone()
547 off = zone->off + sizeof(*oldbuf); in psz_recover_zone()
552 pr_err("read zone %s failed\n", zone->name); in psz_recover_zone()
560 pr_err("read zone %s failed\n", zone->name); in psz_recover_zone()
565 zone->oldbuf = oldbuf; in psz_recover_zone()
566 psz_flush_dirty_zone(zone); in psz_recover_zone()
579 struct pstore_zone *zone; in psz_recover_zones() local
585 zone = zones[i]; in psz_recover_zones()
586 if (unlikely(!zone)) in psz_recover_zones()
588 ret = psz_recover_zone(cxt, zone); in psz_recover_zones()
595 pr_debug("recover %s[%u] failed\n", zone->name, i); in psz_recover_zones()
601 * @cxt: the context of pstore/zone
654 static inline bool psz_old_ok(struct pstore_zone *zone) in psz_old_ok() argument
656 if (zone && zone->oldbuf && atomic_read(&zone->oldbuf->datalen)) in psz_old_ok()
661 static inline bool psz_ok(struct pstore_zone *zone) in psz_ok() argument
663 if (zone && zone->buffer && buffer_datalen(zone)) in psz_ok()
669 struct pstore_zone *zone, struct pstore_record *record) in psz_kmsg_erase() argument
671 struct psz_buffer *buffer = zone->buffer; in psz_kmsg_erase()
676 if (unlikely(!psz_ok(zone))) in psz_kmsg_erase()
679 /* this zone is already updated, no need to erase */ in psz_kmsg_erase()
683 size = buffer_datalen(zone) + sizeof(*zone->buffer); in psz_kmsg_erase()
684 atomic_set(&zone->buffer->datalen, 0); in psz_kmsg_erase()
686 return cxt->pstore_zone_info->erase(size, zone->off); in psz_kmsg_erase()
688 return psz_zone_write(zone, FLUSH_META, NULL, 0, 0); in psz_kmsg_erase()
692 struct pstore_zone *zone) in psz_record_erase() argument
694 if (unlikely(!psz_old_ok(zone))) in psz_record_erase()
697 kfree(zone->oldbuf); in psz_record_erase()
698 zone->oldbuf = NULL; in psz_record_erase()
700 * if there are new data in zone buffer, that means the old data in psz_record_erase()
704 if (!buffer_datalen(zone)) in psz_record_erase()
705 return psz_zone_write(zone, FLUSH_META, NULL, 0, 0); in psz_record_erase()
706 psz_flush_dirty_zone(zone); in psz_record_erase()
733 static void psz_write_kmsg_hdr(struct pstore_zone *zone, in psz_write_kmsg_hdr() argument
737 struct psz_buffer *buffer = zone->buffer; in psz_write_kmsg_hdr()
755 * In case zone is broken, which may occur to MTD device, we try each zones,
762 struct pstore_zone *zone; in psz_kmsg_write_record() local
770 zone = cxt->kpszs[zonenum]; in psz_kmsg_write_record()
771 if (unlikely(!zone)) in psz_kmsg_write_record()
775 len = zone->buffer_size + sizeof(*zone->buffer); in psz_kmsg_write_record()
776 zone->oldbuf = zone->buffer; in psz_kmsg_write_record()
777 zone->buffer = kzalloc(len, GFP_ATOMIC); in psz_kmsg_write_record()
778 if (!zone->buffer) { in psz_kmsg_write_record()
779 zone->buffer = zone->oldbuf; in psz_kmsg_write_record()
782 zone->buffer->sig = zone->oldbuf->sig; in psz_kmsg_write_record()
784 pr_debug("write %s to zone id %d\n", zone->name, zonenum); in psz_kmsg_write_record()
785 psz_write_kmsg_hdr(zone, record); in psz_kmsg_write_record()
787 size = min_t(size_t, record->size, zone->buffer_size - hlen); in psz_kmsg_write_record()
788 ret = psz_zone_write(zone, FLUSH_ALL, record->buf, size, hlen); in psz_kmsg_write_record()
792 /* no need to try next zone, free last zone buffer */ in psz_kmsg_write_record()
793 kfree(zone->oldbuf); in psz_kmsg_write_record()
794 zone->oldbuf = NULL; in psz_kmsg_write_record()
798 pr_debug("zone %u may be broken, try next dmesg zone\n", in psz_kmsg_write_record()
800 kfree(zone->buffer); in psz_kmsg_write_record()
801 zone->buffer = zone->oldbuf; in psz_kmsg_write_record()
802 zone->oldbuf = NULL; in psz_kmsg_write_record()
836 static int notrace psz_record_write(struct pstore_zone *zone, in psz_record_write() argument
844 if (!zone || !record) in psz_record_write()
847 if (atomic_read(&zone->buffer->datalen) >= zone->buffer_size) in psz_record_write()
852 if (unlikely(cnt > zone->buffer_size)) { in psz_record_write()
853 buf += cnt - zone->buffer_size; in psz_record_write()
854 cnt = zone->buffer_size; in psz_record_write()
857 start = buffer_start(zone); in psz_record_write()
858 rem = zone->buffer_size - start; in psz_record_write()
860 psz_zone_write(zone, FLUSH_PART, buf, rem, start); in psz_record_write()
867 atomic_set(&zone->buffer->start, cnt + start); in psz_record_write()
868 psz_zone_write(zone, FLUSH_PART, buf, cnt, start); in psz_record_write()
874 * beginning of zone, which make buffer->datalen wrongly. in psz_record_write()
879 atomic_set(&zone->buffer->datalen, zone->buffer_size); in psz_record_write()
880 psz_zone_write(zone, FLUSH_META, NULL, 0, 0); in psz_record_write()
923 struct pstore_zone *zone = NULL; in psz_read_next_zone() local
926 zone = cxt->kpszs[cxt->kmsg_read_cnt++]; in psz_read_next_zone()
927 if (psz_ok(zone)) in psz_read_next_zone()
928 return zone; in psz_read_next_zone()
935 * all zones in case of some zone without data. in psz_read_next_zone()
941 zone = cxt->ppsz; in psz_read_next_zone()
942 if (psz_old_ok(zone)) in psz_read_next_zone()
943 return zone; in psz_read_next_zone()
948 zone = cxt->cpsz; in psz_read_next_zone()
949 if (psz_old_ok(zone)) in psz_read_next_zone()
950 return zone; in psz_read_next_zone()
955 zone = cxt->bpsz; in psz_read_next_zone()
956 if (psz_old_ok(zone)) in psz_read_next_zone()
957 return zone; in psz_read_next_zone()
963 static int psz_kmsg_read_hdr(struct pstore_zone *zone, in psz_kmsg_read_hdr() argument
966 struct psz_buffer *buffer = zone->buffer; in psz_kmsg_read_hdr()
980 static ssize_t psz_kmsg_read(struct pstore_zone *zone, in psz_kmsg_read() argument
985 size = buffer_datalen(zone); in psz_kmsg_read()
987 if (psz_kmsg_read_hdr(zone, record)) { in psz_kmsg_read()
988 atomic_set(&zone->buffer->datalen, 0); in psz_kmsg_read()
989 atomic_set(&zone->dirty, 0); in psz_kmsg_read()
1010 size = psz_zone_read_buffer(zone, record->buf + hlen, size, in psz_kmsg_read()
1021 static ssize_t psz_ftrace_read(struct pstore_zone *zone, in psz_ftrace_read() argument
1028 if (!zone || !record) in psz_ftrace_read()
1031 if (!psz_old_ok(zone)) in psz_ftrace_read()
1034 buf = (struct psz_buffer *)zone->oldbuf; in psz_ftrace_read()
1046 /* then, read next ftrace zone */ in psz_ftrace_read()
1052 static ssize_t psz_record_read(struct pstore_zone *zone, in psz_record_read() argument
1058 if (!zone || !record) in psz_record_read()
1061 buf = (struct psz_buffer *)zone->oldbuf; in psz_record_read()
1070 if (unlikely(psz_zone_read_oldbuf(zone, record->buf, len, 0))) { in psz_record_read()
1081 ssize_t (*readop)(struct pstore_zone *zone, in psz_pstore_read()
1083 struct pstore_zone *zone; in psz_pstore_read() local
1092 zone = psz_read_next_zone(cxt); in psz_pstore_read()
1093 if (!zone) in psz_pstore_read()
1096 record->type = zone->type; in psz_pstore_read()
1114 ret = readop(zone, record); in psz_pstore_read()
1136 struct pstore_zone *zone = *pszone; in psz_free_zone() local
1138 if (!zone) in psz_free_zone()
1141 kfree(zone->buffer); in psz_free_zone()
1142 kfree(zone); in psz_free_zone()
1179 struct pstore_zone *zone; in psz_init_zone() local
1191 zone = kzalloc(sizeof(struct pstore_zone), GFP_KERNEL); in psz_init_zone()
1192 if (!zone) in psz_init_zone()
1195 zone->buffer = kmalloc(size, GFP_KERNEL); in psz_init_zone()
1196 if (!zone->buffer) { in psz_init_zone()
1197 kfree(zone); in psz_init_zone()
1200 memset(zone->buffer, 0xFF, size); in psz_init_zone()
1201 zone->off = *off; in psz_init_zone()
1202 zone->name = name; in psz_init_zone()
1203 zone->type = type; in psz_init_zone()
1204 zone->buffer_size = size - sizeof(struct psz_buffer); in psz_init_zone()
1205 zone->buffer->sig = type ^ PSZ_SIG; in psz_init_zone()
1206 zone->oldbuf = NULL; in psz_init_zone()
1207 atomic_set(&zone->dirty, 0); in psz_init_zone()
1208 atomic_set(&zone->buffer->datalen, 0); in psz_init_zone()
1209 atomic_set(&zone->buffer->start, 0); in psz_init_zone()
1213 pr_debug("pszone %s: off 0x%llx, %zu header, %zu data\n", zone->name, in psz_init_zone()
1214 zone->off, sizeof(*zone->buffer), zone->buffer_size); in psz_init_zone()
1215 return zone; in psz_init_zone()
1223 struct pstore_zone **zones, *zone; in psz_init_zones() local
1246 zone = psz_init_zone(type, off, record_size); in psz_init_zones()
1247 if (!zone || IS_ERR(zone)) { in psz_init_zones()
1250 return (void *)zone; in psz_init_zones()
1252 zones[i] = zone; in psz_init_zones()
1319 * register_pstore_zone() - register to pstore/zone
1462 * unregister_pstore_zone() - unregister to pstore/zone
1491 /* Clear counters and zone state. */ in unregister_pstore_zone()