* This function will prune commit itxs that are at the head of the * commit list (it won't prune past the first non-commit itx), and * either: a) attach them to the last lwb that's still pending * completion, or b) skip them altogether. * * This is used as a performance optimization to prevent commit itxs * from generating new lwbs when it's unnecessary to do so. */
| 2162 | * from generating new lwbs when it's unnecessary to do so. |
| 2163 | */ |
| 2164 | static void |
| 2165 | zil_prune_commit_list(zilog_t *zilog) |
| 2166 | { |
| 2167 | itx_t *itx; |
| 2168 | |
| 2169 | ASSERT(MUTEX_HELD(&zilog->zl_issuer_lock)); |
| 2170 | |
| 2171 | while ((itx = list_head(&zilog->zl_itx_commit_list)) != NULL) { |
| 2172 | lr_t *lrc = &itx->itx_lr; |
| 2173 | if (lrc->lrc_txtype != TX_COMMIT) |
| 2174 | break; |
| 2175 | |
| 2176 | mutex_enter(&zilog->zl_lock); |
| 2177 | |
| 2178 | lwb_t *last_lwb = zilog->zl_last_lwb_opened; |
| 2179 | if (last_lwb == NULL || |
| 2180 | last_lwb->lwb_state == LWB_STATE_FLUSH_DONE) { |
| 2181 | /* |
| 2182 | * All of the itxs this waiter was waiting on |
| 2183 | * must have already completed (or there were |
| 2184 | * never any itx's for it to wait on), so it's |
| 2185 | * safe to skip this waiter and mark it done. |
| 2186 | */ |
| 2187 | zil_commit_waiter_skip(itx->itx_private); |
| 2188 | } else { |
| 2189 | zil_commit_waiter_link_lwb(itx->itx_private, last_lwb); |
| 2190 | itx->itx_private = NULL; |
| 2191 | } |
| 2192 | |
| 2193 | mutex_exit(&zilog->zl_lock); |
| 2194 | |
| 2195 | list_remove(&zilog->zl_itx_commit_list, itx); |
| 2196 | zil_itx_destroy(itx); |
| 2197 | } |
| 2198 | |
| 2199 | IMPLY(itx != NULL, itx->itx_lr.lrc_txtype != TX_COMMIT); |
| 2200 | } |
| 2201 | |
| 2202 | static void |
| 2203 | zil_commit_writer_stall(zilog_t *zilog) |
no test coverage detected