fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dynamic memory support
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_dealloc_dm(void);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _sd_entry_availability_dm(_sd_cctl_t *cc_ent, int *nodata);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern void sdbc_requeue_dmchain(_sd_queue_t *, _sd_cctl_t *, int, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern void sdbc_ins_dmqueue_front(_sd_queue_t *q, _sd_cctl_t *cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern void sdbc_remq_dmchain(_sd_queue_t *q, _sd_cctl_t *cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern void sdbc_requeue_head_dm_try(_sd_cctl_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* secret flush toggle flag for testing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint _sdbc_flush_flag = 1; /* 0 ==> noflushing, 1 ==> flush */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Forward declare all statics that are used before defined to enforce
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parameter checking
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some (if not all) of these could be removed if the code were reordered
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_flcent_ea(blind_t xcc_ent, nsc_off_t fba_pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_flclist_ea(blind_t xcc_ent, nsc_off_t fba_pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_process_reflush(_sd_cctl_t *cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_flush_thread(void);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (void (*)(void *))_sd_flush_thread, 0, TRUE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (centry = sdbc_centry_alloc_blks(_CD_NOHASH, 0, reqblks,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* release the blocks to the queue */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int reqblks = MEGABYTE/BLK_SIZE(1); /* alloc in mb chunks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sdbc_static_cache) { /* alloc all static cache memory here */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < blk_groups; ++i) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* if successful then allocate any remaining blocks */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!Failed to allocate sdbc cache "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "memory.\n requested mem: %d MB; actual mem: %d MB",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_NOTE, "!sdbc(_sdbc_dealloc_configure_dm) %d bytes "
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "(%d cache blocks) allocated for static cache, "
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "block size %d", blks_allocd * BLK_SIZE(1), blks_allocd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* DEBUG */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = nsc_create_process((void (*)(void *))_sd_dealloc_dm, 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sdbc_dealloc_dm_shutdown - deallocate cache memory.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS: none
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS: nothing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this function is intended for use after all i/o has stopped and all
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * other cache threads have terminated. write cache resources, if any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are released, except in the case of pinned data.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* HOST or OTHER */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE2(sdbc_dealloc_dm_shutdown, char *,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cc_ent->cc_data, int, cc_ent->cc_alloc_size_dm);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* release safestore resource, if any. preserve pinned data */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(CENTRY_DIRTY(cc_ent)) && (wctl = cc_ent->cc_write)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SSOP_DEALLOCRESOURCE(sdbc_safestore, wctl->sc_res);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return; /* thread never started */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&dynmem_processing_dm.thread_dm_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_broadcast(&dynmem_processing_dm.thread_dm_cv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&dynmem_processing_dm.thread_dm_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (sd_dealloc_flag_dm != CACHE_THREAD_TERMINATED_DM)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This complicated - possibly overly complicated routine works as follows:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In general the routine sleeps a specified amount of time then wakes and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * examines the entire centry list. If an entry is avail. it ages it by one
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tick else it clears the aging flag completely. It then determines if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * centry has aged sufficiently to have its memory deallocated and for it to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be placed at the top of the lru.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There are two deallocation schemes in place depending on whether the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * centry is a standalone entry or it is a member of a host/parasite chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The behavior for a standalone entry is as follows:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the given centry is selected it will age normally however at full
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * aging it will only be placed at the head of the lru. It's memory will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not be deallocated until a further aging level has been reached. The
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * entries selected for this behavior are goverend by counting the number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of these holdovers in existence on each wakeup and and comparing it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to a specified percentage. This comparision is always one cycle out of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * date and will float in the relative vicinity of the specified number.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The behavior for a host/parasite chain is as follows:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The chain is examined. If all entries are fully aged the entire chain
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is removed - ie mem is dealloc. from the host entry and all memory ref.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * removed from the parasitic entries and each entry requeued on to the lru.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * There are three delay timeouts and two percentage levels specified. Timeout
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * level 1 is honored between 100% free and pcnt level 1. Timeout level 2 is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * honored between pcnt level 1 and pcnt level 2, Timeout level 3 is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * honored between pcnt level 2 and 0% free. In addition there exist an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * accelerated
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * aging flag which mimics hysterisis behavior. If the available centrys fall
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * between pcnt1 and pcnt2 an 8 bit counter is switched on. The effect is to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * keep the timer value at timer level 2 for 8 cycles even if the number
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * available cache entries drifts above pcnt1. If it falls below pcnt2 an
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * additional 8 bit counter is switched on. This causes the sleep timer to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remain at timer level 3 for at least 8 cycles even if it floats above
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pcnt2 or even pcnt1. The effect of all this is to accelerate the release
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of system resources under a heavy load.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All of the footwork can be stubbed out by a judicious selection of values
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * for the times, aging counts and pcnts.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All of these behavior parameters are adjustable on the fly via the kstat
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * mechanism. In addition there is a thread wakeup msg available through the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * same mechanism.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sleep_tics_lvl1, sleep_tics_lvl2, sleep_tics_lvl3;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int host_cache_aging_ct, meta_cache_aging_ct, hold_cache_aging_ct;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cache_aging_ct, hold_candidate, last_holds_ct;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_cctl_t *cc_ent, *next_ccentry, *cur_ent, *nxt_ent;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int current_breakout_count, number_cache_entries;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* setup a one sec time var */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*CONSTANTCONDITION*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* finished. shutdown - get out */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_dealloc_dm_shutdown(); /* free all memory */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* has the world changed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * get num cctl entries (%) below which different sleep
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * rates kick in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ppvars->cache_aging_pcnt1*number_cache_entries) / 100;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (ppvars->cache_aging_pcnt2*number_cache_entries) / 100;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get sleep rates for each level */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sleep_tics_lvl1 = ppvars->cache_aging_sec1 * one_sec_tics;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sleep_tics_lvl2 = ppvars->cache_aging_sec2 * one_sec_tics;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sleep_tics_lvl3 = ppvars->cache_aging_sec3 * one_sec_tics;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get num of cycles for full normal aging */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get num of cycles for full meta aging */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get num of cycles for full extended holdover aging */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* get maximum holds count in % */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_holds_ct = (ppvars->max_holds_pcnt*number_cache_entries)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* apply the delay */
d3d50737e566cade9a08d73d2af95105ac7cd960Rafael Vanoni &ppvars->thread_dm_lock, tic_delay, TR_CLOCK_TICK);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check for special directives on wakeup */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Start of deallocation loop */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (sd_dealloc_flag_dm != CACHE_SHUTDOWN_DM &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_entry_availability_dm(cc_ent, &ppvars->nodatas)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* bonafide aged entry - examine its chain */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* chain not fully free - free inuse for all entries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else { /* OK - free memory */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* if (hold_candidate == TRUE */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* HOST or OTHER */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* debugging */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * remove from queue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in preparation for putting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on the 0 queue after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * memory is freed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* while (cur_ent) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* else OK - free memory */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* while (entries) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ppvars->monitor_dynmem_process & RPT_DEALLOC_STATS1_DM) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!notavl=%x, nodat=%x, cand=%x, hosts=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " pests=%x, metas=%x, holds=%x, others=%x,"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte " deallo=%x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ppvars->candidates, ppvars->hosts, ppvars->pests,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ppvars->monitor_dynmem_process & RPT_DEALLOC_STATS2_DM) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!hist=%x, gross a/d=%x %x", ppvars->history,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* set the history flag which will govern the sleep rate */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* upper - lots of virgin cctls */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* middle - not so many virgin cctls */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * appear to be running low - accelerate the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * aging to free more
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } /* while (TRUE) */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_entry_availability_dm(_sd_cctl_t *cc_ent, int *nodata)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if using dmchaining return immediately and do not attempt
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to acquire the cc_ent if there is no memory associated with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this cc_ent.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this avoids conflicts for centrys on the 0 queue.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * see sdbc_get_dmchain()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((sdbc_use_dmchain) && (cc_ent->cc_data == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we allow the QHEAD flag as it does not affect the availabilty
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of memory for aging
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((CENTRY_DIRTY(cc_ent)) || (CENTRY_IO_INPROGRESS(cc_ent)) ||
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cc_ent->cc_dirty_next || cc_ent->cc_dirty_link ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * function below to prohibit code movement by compiler
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and avoid using spinlocks for syncronization
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Yet another switch!
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * alloc mem and coalesce if at least this number of frags
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * optimization for _sd_async_flclist()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called only if not doing pageio and sdbc_coalesce_backend > 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returns with pagio bit set in the centrys in list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic unsigned char *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesdbc_alloc_io_mem(_sd_cctl_t *cc_ent, int first_dirty, int last_dirty)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unsigned char *start_addr = NULL; /* function return value */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* check for contiguity */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana !((prev_addr + CACHE_BLOCK_SIZE) == cc_ent->cc_data))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* compute length */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * TODO - determine metric for deciding
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * whether to coalesce memory or do separate i/o's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (start_addr = kmem_alloc(total_len_bytes, KM_NOSLEEP)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy the first dirty piece */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* copy the rest of data */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana 0, BLK_TO_FBA_NUM(CENTRY_BLK(cclist)), 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte coalesce = (!sdbc_do_page && sdbc_coalesce_backend);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty)))
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana if (coalesce && (anon_mem = sdbc_alloc_io_mem(cc_ent, first_dirty,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (first_dirty && (!_SD_BMAP_ISFULL(first_dirty))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* pageio bit already set in sdbc_alloc_io_mem() above */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* build buffer only if it was not done above */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE4(_sd_async_flclist_data1, int,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana *(int64_t *)(cc_ent->cc_data + FBA_SIZE(i)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* pageio bit already set in sdbc_alloc_io_mem() above */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* build buffer only if it was not done above */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * consistency check.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!_sd_err: flclist: last_dirty %x next %x",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* build buffer only if it was not done above */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE4(_sd_async_flclist_data3, int,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* SDTRACE(ST_INFO|SDF_FLCLIST, cd, FBA_NUM(len), dblk, flushed, bp); */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sd_start_io(bp, _sd_cache_files[cd].cd_strategy,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* increment number of bytes destaged to disk */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SDTRACE(ST_EXIT|SDF_FLCLIST, cd, FBA_NUM(len), dblk, flushed, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_enqueue_io_pending(int cd, _sd_cctl_t *cclist)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana SDALERT(SDF_FLCENT, cd, 0, BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana int, BLK_FBAS, char *, *(int64_t *)(cc_ent->cc_data),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sd_start_io(bp, _sd_cache_files[cd].cd_strategy,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* increment number of bytes destaged to disk */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dblk = BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)) + sblk;
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana int, len, char *,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana *(int64_t *)(cc_ent->cc_data + FBA_SIZE(sblk)),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* SDTRACE(ST_INFO|SDF_FLCENT, cd, len, dblk, 0, bp); */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sd_start_io(bp, _sd_cache_files[cd].cd_strategy,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* increment number of bytes destaged to disk */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana SDT_INV_BL, cdi->cd_info->sh_numio, processed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((sts = cc_ent->cc_iostatus) == _SD_IO_INITIATE) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana SDT_INV_BL, cdi->cd_info->sh_numio, processed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((sts != _SD_IO_DONE) && (sts != _SD_IO_FAILED))
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)), 0, sts);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cdi->cd_io_head = cc_ent->cc_dirty_link) == NULL)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE1(_sd_process_pending_cd, int, cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Optimize for common case where block not inuse
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Grabbing cc_inuse is faster than cc_lock.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SSOP_DEALLOCRESOURCE(sdbc_safestore, wctl->sc_res);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if this was a QHEAD cache block, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_centry_release() did not requeue it as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it was dirty. Requeue it now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* attempt to que head */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Block is inuse, must take cc_lock
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if DIRTY_PENDING, must re-issue
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * clear dirty bits, if block no longer inuse release cc_write
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SSOP_DEALLOCRESOURCE(sdbc_safestore, wctl->sc_res);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if this was a QHEAD cache block, then
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_centry_release() did not requeue it as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it was dirty. Requeue it now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* attempt to que head */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_enqueue_dirty_chain(cd, dirty_hd, (*dirty_nxt), dirty_enq);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_flcent_ea(blind_t xcc_ent, nsc_off_t fba_pos, nsc_size_t fba_len, int error)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SDTRACE(ST_ENTER|SDF_FLCENT_EA, cd, 0, dblk, 2, (unsigned long)cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Disk write failed cd %d (%s): err %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* more io's to complete before the cc_ent is done. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (unsigned long)cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DATA_LOG(SDF_FLEA, cc_ent, BLK_FBA_OFF(fba_pos), fba_len);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE4(_sd_flcent_ea_data, uint64_t, ((uint64_t)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent) + BLK_FBA_OFF(fba_pos))),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana *(int64_t *)(cc_ent->cc_data + FBA_SIZE(BLK_FBA_OFF(fba_pos))),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana FBA_SIZE(BLK_FBA_OFF(fba_pos) + fba_len) - 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * All io's are done for this cc_ent.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clear the pagelist io flag.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SDTRACE(ST_EXIT|SDF_FLCENT_EA, cd, 0, dblk, 2, (unsigned long)cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_flclist_ea(blind_t xcc_ent, nsc_off_t fba_pos, nsc_size_t fba_len,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SDTRACE(ST_ENTER|SDF_FLCLIST_EA, cd, 0, dblk, 1, (unsigned long)cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Disk write failed cd %d (%s): err %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Important: skip the first cc_ent in the list. Marking this will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * make the writer think the io is done, though the rest of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * chain have not been processed here. so mark the first cc_ent
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * last. Optimization, so as not to use locks
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE2(_sd_flclist_ea, _sd_cctl_t *, cc_ent,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clear the pagelist io flag.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE4(_sd_flclist_ea_data1, uint64_t,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE4(_sd_flclist_ea_data2, uint64_t,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (uint64_t)BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana uint64_t, (uint64_t)BLK_FBA_OFF(fba_pos + fba_len),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana FBA_SIZE(BLK_FBA_OFF(fba_pos + fba_len)) - 8));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now process the first cc_ent in the list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DATA_LOG(SDF_FLSTEA, cc_ent, BLK_FBA_OFF(fba_pos),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE4(_sd_flclist_ea_data3, uint64_t,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (uint64_t)fba_pos, int, BLK_FBAS - BLK_FBA_OFF(fba_pos),
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana *(int64_t *)(cc_ent->cc_data + FBA_SIZE(BLK_FBA_OFF(fba_pos) +
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(cc_ent->cc_anon_addr.sa_virt, cc_ent->cc_anon_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Clear the pagelist io flag.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SDTRACE(ST_EXIT|SDF_FLCLIST_EA, cd, 0, dblk, 1, (unsigned long)cc_ent);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Fail single chain of cache blocks, updating numfail/numio counts.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For dual-copy, log & clear PINNED, fall thru to regular processing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (num = 0; cc_ent; cc_ent = cc_ent->cc_dirty_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SSOP_SETCENTRY(sdbc_safestore, cc_ent->cc_write);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * In normal processing we wouldn't need a lock here as all i/o
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is single threaded by cd. However during failover blocks can
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be failing from real i/o and as soon as the disk is marked bad
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the failover code which is furiously cloning safe-store into
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * more blocks will short circuit to here (see _sd_ft_clone)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and two threads can be executing in here simultaneously.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana BLK_TO_FBA_NUM(CENTRY_BLK(cc_ent)), BLK_FBAS);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cd_write_thread -- flush dirty buffers.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cd - cache descriptor
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called by cd's writer thread, returns when no more entries
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: if sdbc is being shutdown (for powerfail) then we will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * process pending i/o's but issue no more new ones.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int SD_WRITE_HIGH = 255; /* cache blocks */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* let I/Os complete before issuing more */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!_sdbc_flush_flag) { /* hang the flusher for testing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (dirty_head && (dirty_head != cdi->cd_lastchain_ptr ||
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana ++cdi->cd_info->sh_flushloop > SD_LOOP_DELAY)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->cd_info->sh_numio += cdi->cd_info->sh_numdirty;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* cdi->cd_dirty_tail is unchanged */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cdi->cd_info->sh_numio += cdi->cd_info->sh_numdirty -
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* was FAST */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cd_writer -- spawn new writer if not running already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * called after enqueing the dirty blocks
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_USE_THREADS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cdi->cd_writer || xmem_bu(_SD_WRITER_CREATE, &cdi->cd_writer))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t = nst_create(tset, cd_write_thread, (blind_t)(unsigned long)cd, 0);
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!sdbc(cd_writer) cd %d nst_create error", cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_ccent_rd - add appropriate parts of cc_ent to struct buf.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * optimized not to read dirty FBAs from disk.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * cc_ent - single cache block
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wanted - bitlist of FBAs that need to be read
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - struct buf to extend
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called for each dirty in a read I/O.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The bp must be sized to allow for one entry per FBA that needs
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to be read (see _sd_doread()).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_ccent_rd(_sd_cctl_t *cc_ent, uint_t wanted, struct buf *bp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int state, state1 = -3; /* state1 is previous state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (state == state1) /* same state, expand size */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_USE_THREADS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* .2 seconds */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* .02 seconds */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * wait until no i/o's pending (on two successive
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iterations) or we see no progress after
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * GIVE_UP_WAITING total sleeps.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* at most 5*128 ticks about 6 seconds of no progress */
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!_sd_flush_thread "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "exiting with %d IOs "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Normally wakeup every SD_LONG_SLEEP_TICS to flush.
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sdbc(_sd_flush_thread)"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "cannot get safestore inq");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < 8; i++, data += 128, fba_pos++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < fba_len; i++, data += 128, fpos++) {
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!%s exp%" NSC_SZFMT " got%x",
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana cmn_err(CE_WARN, "!len %" NSC_SZFMT " real %" NSC_SZFMT, len,