Commit aecba2e0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull power management fixes from Rafael Wysocki:
 "These fix issues related to the handling of compressed hibernation
  images and a recent intel_pstate driver regression:

   - Fix issues related to using inadequate data types and incorrect use
     of atomic variables in the compressed hibernation images handling
     code that were introduced during the 6.9 development cycle (Mario
     Limonciello)

   - Move a X86_FEATURE_IDA check from turbo_is_disabled() to the places
     where a new value for MSR_IA32_PERF_CTL is computed in intel_pstate
     to address a regression preventing users from enabling turbo
     frequencies post-boot (Srinivas Pandruvada)"

* tag 'pm-6.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: intel_pstate: Check IDA only before MSR_IA32_PERF_CTL writes
  PM: hibernate: Fix style issues in save_compressed_image()
  PM: hibernate: Use atomic64_t for compressed_size variable
  PM: hibernate: Emit an error when image writing fails
parents 6a3cc1b7 161284b2
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -603,9 +603,6 @@ static bool turbo_is_disabled(void)
{
	u64 misc_en;

	if (!cpu_feature_enabled(X86_FEATURE_IDA))
		return true;

	rdmsrq(MSR_IA32_MISC_ENABLE, misc_en);

	return !!(misc_en & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
@@ -2106,7 +2103,8 @@ static u64 atom_get_val(struct cpudata *cpudata, int pstate)
	u32 vid;

	val = (u64)pstate << 8;
	if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled))
	if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled) &&
	    cpu_feature_enabled(X86_FEATURE_IDA))
		val |= (u64)1 << 32;

	vid_fp = cpudata->vid.min + mul_fp(
@@ -2271,7 +2269,8 @@ static u64 core_get_val(struct cpudata *cpudata, int pstate)
	u64 val;

	val = (u64)pstate << 8;
	if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled))
	if (READ_ONCE(global.no_turbo) && !READ_ONCE(global.turbo_disabled) &&
	    cpu_feature_enabled(X86_FEATURE_IDA))
		val |= (u64)1 << 32;

	return val;
+13 −9
Original line number Diff line number Diff line
@@ -635,7 +635,7 @@ struct cmp_data {
};

/* Indicates the image size after compression */
static atomic_t compressed_size = ATOMIC_INIT(0);
static atomic64_t compressed_size = ATOMIC_INIT(0);

/*
 * Compression function that runs in its own thread.
@@ -664,7 +664,7 @@ static int compress_threadfn(void *data)
		d->ret = crypto_acomp_compress(d->cr);
		d->cmp_len = d->cr->dlen;

		atomic_set(&compressed_size, atomic_read(&compressed_size) + d->cmp_len);
		atomic64_add(d->cmp_len, &compressed_size);
		atomic_set_release(&d->stop, 1);
		wake_up(&d->done);
	}
@@ -689,14 +689,14 @@ static int save_compressed_image(struct swap_map_handle *handle,
	ktime_t start;
	ktime_t stop;
	size_t off;
	unsigned thr, run_threads, nr_threads;
	unsigned int thr, run_threads, nr_threads;
	unsigned char *page = NULL;
	struct cmp_data *data = NULL;
	struct crc_data *crc = NULL;

	hib_init_batch(&hb);

	atomic_set(&compressed_size, 0);
	atomic64_set(&compressed_size, 0);

	/*
	 * We'll limit the number of threads for compression to limit memory
@@ -877,11 +877,14 @@ static int save_compressed_image(struct swap_map_handle *handle,
	stop = ktime_get();
	if (!ret)
		ret = err2;
	if (!ret)
		pr_info("Image saving done\n");
	if (!ret) {
		swsusp_show_speed(start, stop, nr_to_write, "Wrote");
	pr_info("Image size after compression: %d kbytes\n",
		(atomic_read(&compressed_size) / 1024));
		pr_info("Image size after compression: %lld kbytes\n",
			(atomic64_read(&compressed_size) / 1024));
		pr_info("Image saving done\n");
	} else {
		pr_err("Image saving failed: %d\n", ret);
	}

out_clean:
	hib_finish_batch(&hb);
@@ -899,7 +902,8 @@ static int save_compressed_image(struct swap_map_handle *handle,
		}
		vfree(data);
	}
	if (page) free_page((unsigned long)page);
	if (page)
		free_page((unsigned long)page);

	return ret;
}