LWN.net Logo

btrfs_get_temp()

This is btrfs_get_tmp(), from the Btrfs hot data tracking patch set.

/*
 * Function that converts btrfs_freq_data structs to integer temperature
 * values, determined by some constants in .h.
 *
 * This is not very calibrated, though we've gotten it in the ballpark.
 */
int btrfs_get_temp(struct btrfs_freq_data *fdata)
{
	u32 result = 0;

	struct timespec ckt = current_kernel_time();
	u64 cur_time = timespec_to_ns(&ckt);

	u32 nrr_heat = fdata->nr_reads << NRR_MULTIPLIER_POWER;
	u32 nrw_heat = fdata->nr_writes << NRW_MULTIPLIER_POWER;

	u64 ltr_heat = (cur_time - timespec_to_ns(&fdata->last_read_time))
			>> LTR_DIVIDER_POWER;
	u64 ltw_heat = (cur_time - timespec_to_ns(&fdata->last_write_time))
			>> LTW_DIVIDER_POWER;

	u64 avr_heat = (((u64) -1) - fdata->avg_delta_reads)
			>> AVR_DIVIDER_POWER;
	u64 avw_heat = (((u64) -1) - fdata->avg_delta_writes)
			>> AVR_DIVIDER_POWER;

	if (ltr_heat >= ((u64) 1 << 32))
		ltr_heat = 0;
	else
		ltr_heat = ((u64) 1 << 32) - ltr_heat;
	/* ltr_heat is now guaranteed to be u32 safe */

	if (ltw_heat >= ((u64) 1 << 32))
		ltw_heat = 0;
	else
		ltw_heat = ((u64) 1 << 32) - ltw_heat;
	/* ltw_heat is now guaranteed to be u32 safe */

	if (avr_heat >= ((u64) 1 << 32))
		avr_heat = (u32) -1;
	/* avr_heat is now guaranteed to be u32 safe */

	if (avw_heat >= ((u64) 1 << 32))
		avr_heat = (u32) -1;
	/* avw_heat is now guaranteed to be u32 safe */

	nrr_heat = nrr_heat >> (3 - NRR_COEFF_POWER);
	nrw_heat = nrw_heat >> (3 - NRW_COEFF_POWER);
	ltr_heat = ltr_heat >> (3 - LTR_COEFF_POWER);
	ltw_heat = ltw_heat >> (3 - LTW_COEFF_POWER);
	avr_heat = avr_heat >> (3 - AVR_COEFF_POWER);
	avw_heat = avw_heat >> (3 - AVW_COEFF_POWER);

	result = nrr_heat + nrw_heat + (u32) ltr_heat +
		 (u32) ltw_heat + (u32) avr_heat + (u32) avw_heat;

	return result >> (32 - HEAT_HASH_BITS);
}

(Log in to post comments)

Copyright © 2010, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds