#define DED_WEIGHT 0xffff /* * CP and IFL as EBCDIC strings, SP/0x40 determines the end of string * as they are justified with spaces.
*/ #define CP 0xc3d7404040404040UL #define IFL 0xc9c6d34040404040UL
/* * STHYI requires extensive locking in the higher hypervisors * and is very computational/memory expensive. Therefore we * cache the retrieved data whose valid period is 1s.
*/ #define CACHE_VALID_JIFFIES HZ
/* * Scales the cpu capping from the lpar range to the one expected in * sthyi data. * * diag204 reports a cap in hundredths of processor units. * z/VM's range for one core is 0 - 0x10000.
*/ static u32 scale_cap(u32 in)
{ return (0x10000 * in) / 100;
}
staticbool is_diag204_cached(struct sthyi_sctns *sctns)
{ /* * Check if validity bits are set when diag204 data * is gathered.
*/ if (sctns->par.infpval1) returntrue; returnfalse;
}
for (i = 0; i < ti_hdr->npar; i++) { /* * For the calling lpar we also need to get the cpu * caps and weights. The time information block header * specifies the offset to the partition block of the * caller lpar, so we know when we process its data.
*/
this_lpar = (void *)part_block - diag204_buf == ti_hdr->this_part;
part_block = lpar_cpu_inf(&lpar_inf, this_lpar, diag224_buf,
part_block);
}
/* * Everything below needs global performance data to be * meaningful.
*/ if (!(ti_hdr->flags & DIAG204_LPAR_PHYS_FLG)) {
sctns->hdr.infhflg1 |= HDR_PERF_UNAV; goto out;
}
/* * If the facility is on, we don't want to emulate the instruction. * We ask the hypervisor to provide the data.
*/ if (test_facility(74)) {
memset(dst, 0, PAGE_SIZE); return sthyi((u64)dst, rc);
} /* * When emulating, if diag204 returns BUSY don't reset dst buffer * and use cached data.
*/
*rc = 0;
diag204_buf = diag204_get_data(is_diag204_cached(sctns)); if (IS_ERR(diag204_buf)) return PTR_ERR(diag204_buf);
memset(dst, 0, PAGE_SIZE);
fill_hdr(sctns);
fill_stsi(sctns);
fill_diag(sctns, diag204_buf);
vfree(diag204_buf); return 0;
}
r = fill_dst(sthyi_cache.info, rc); if (r == 0) {
sthyi_cache.end = jiffies + CACHE_VALID_JIFFIES;
} elseif (r == -EBUSY) { /* mark as expired and return 0 to keep using cached data */
sthyi_cache.end = jiffies - 1;
r = 0;
} return r;
}
/* * sthyi_fill - Fill page with data returned by the STHYI instruction * * @dst: Pointer to zeroed page * @rc: Pointer for storing the return code of the instruction * * Fills the destination with system information returned by the STHYI * instruction. The data is generated by emulation or execution of STHYI, * if available. The return value is either a negative error value or * the condition code that would be returned, the rc parameter is the * return code which is passed in register R2 + 1.
*/ int sthyi_fill(void *dst, u64 *rc)
{ int r;
mutex_lock(&sthyi_mutex);
r = sthyi_init_cache(); if (r) goto out;
if (time_is_before_jiffies(sthyi_cache.end)) { /* cache expired */
r = sthyi_update_cache(rc); if (r) goto out;
}
*rc = 0;
memcpy(dst, sthyi_cache.info, PAGE_SIZE);
out:
mutex_unlock(&sthyi_mutex); return r;
}
EXPORT_SYMBOL_GPL(sthyi_fill);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.