| 167 | #define PG2MB(pgs) ((pgs + (1 << (20 - PAGE_SHIFT)) - 1) >> (20 - PAGE_SHIFT)) |
| 168 | |
| 169 | int |
| 170 | dumpsys_cb_dumpdata(struct dump_pa *mdp, int seqnr, void *arg) |
| 171 | { |
| 172 | struct dumperinfo *di = (struct dumperinfo*)arg; |
| 173 | vm_paddr_t pa; |
| 174 | void *va; |
| 175 | uint64_t pgs; |
| 176 | size_t counter, sz, chunk; |
| 177 | int c, error; |
| 178 | u_int maxdumppgs; |
| 179 | |
| 180 | error = 0; /* catch case in which chunk size is 0 */ |
| 181 | counter = 0; /* Update twiddle every 16MB */ |
| 182 | va = NULL; |
| 183 | pgs = mdp->pa_size / PAGE_SIZE; |
| 184 | pa = mdp->pa_start; |
| 185 | maxdumppgs = min(di->maxiosize / PAGE_SIZE, MAXDUMPPGS); |
| 186 | if (maxdumppgs == 0) /* seatbelt */ |
| 187 | maxdumppgs = 1; |
| 188 | |
| 189 | printf(" chunk %d: %juMB (%ju pages)", seqnr, (uintmax_t)PG2MB(pgs), |
| 190 | (uintmax_t)pgs); |
| 191 | |
| 192 | dumpsys_wbinv_all(); |
| 193 | while (pgs) { |
| 194 | chunk = pgs; |
| 195 | if (chunk > maxdumppgs) |
| 196 | chunk = maxdumppgs; |
| 197 | sz = chunk << PAGE_SHIFT; |
| 198 | counter += sz; |
| 199 | if (counter >> 24) { |
| 200 | printf(" %ju", (uintmax_t)PG2MB(pgs)); |
| 201 | counter &= (1 << 24) - 1; |
| 202 | } |
| 203 | |
| 204 | dumpsys_map_chunk(pa, chunk, &va); |
| 205 | wdog_kern_pat(WD_LASTVAL); |
| 206 | |
| 207 | error = dump_append(di, va, 0, sz); |
| 208 | dumpsys_unmap_chunk(pa, chunk, va); |
| 209 | if (error) |
| 210 | break; |
| 211 | pgs -= chunk; |
| 212 | pa += sz; |
| 213 | |
| 214 | /* Check for user abort. */ |
| 215 | c = cncheckc(); |
| 216 | if (c == 0x03) |
| 217 | return (ECANCELED); |
| 218 | if (c != -1) |
| 219 | printf(" (CTRL-C to abort) "); |
| 220 | } |
| 221 | printf(" ... %s\n", (error) ? "fail" : "ok"); |
| 222 | return (error); |
| 223 | } |
| 224 | |
| 225 | int |
| 226 | dumpsys_foreach_chunk(dumpsys_callback_t cb, void *arg) |
nothing calls this directly
no test coverage detected