Commit 5ef3720d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull powerpc fixes from Michael Ellerman:

 - Fix a bug where heavy VAS (accelerator) usage could race with
   partition migration and prevent the migration from completing.

 - Update MAINTAINERS to add Aneesh & Naveen.

Thanks to Haren Myneni.

* tag 'powerpc-6.7-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  MAINTAINERS: powerpc: Add Aneesh & Naveen
  powerpc/pseries/vas: Migration suspend waits for no in-progress open windows
parents dde0672b d2441d3e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -12189,6 +12189,8 @@ LINUX FOR POWERPC (32-BIT AND 64-BIT)
M:	Michael Ellerman <mpe@ellerman.id.au>
R:	Nicholas Piggin <npiggin@gmail.com>
R:	Christophe Leroy <christophe.leroy@csgroup.eu>
R:	Aneesh Kumar K.V <aneesh.kumar@kernel.org>
R:	Naveen N. Rao <naveen.n.rao@linux.ibm.com>
L:	linuxppc-dev@lists.ozlabs.org
S:	Supported
W:	https://github.com/linuxppc/wiki/wiki
+44 −7
Original line number Diff line number Diff line
@@ -385,11 +385,15 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
	 * same fault IRQ is not freed by the OS before.
	 */
	mutex_lock(&vas_pseries_mutex);
	if (migration_in_progress)
	if (migration_in_progress) {
		rc = -EBUSY;
	else
	} else {
		rc = allocate_setup_window(txwin, (u64 *)&domain[0],
				   cop_feat_caps->win_type);
		if (!rc)
			caps->nr_open_wins_progress++;
	}

	mutex_unlock(&vas_pseries_mutex);
	if (rc)
		goto out;
@@ -404,8 +408,17 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
		goto out_free;

	txwin->win_type = cop_feat_caps->win_type;
	mutex_lock(&vas_pseries_mutex);

	/*
	 * The migration SUSPEND thread sets migration_in_progress and
	 * closes all open windows from the list. But the window is
	 * added to the list after open and modify HCALLs. So possible
	 * that migration_in_progress is set before modify HCALL which
	 * may cause some windows are still open when the hypervisor
	 * initiates the migration.
	 * So checks the migration_in_progress flag again and close all
	 * open windows.
	 *
	 * Possible to lose the acquired credit with DLPAR core
	 * removal after the window is opened. So if there are any
	 * closed windows (means with lost credits), do not give new
@@ -413,9 +426,11 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
	 * after the existing windows are reopened when credits are
	 * available.
	 */
	if (!caps->nr_close_wins) {
	mutex_lock(&vas_pseries_mutex);
	if (!caps->nr_close_wins && !migration_in_progress) {
		list_add(&txwin->win_list, &caps->list);
		caps->nr_open_windows++;
		caps->nr_open_wins_progress--;
		mutex_unlock(&vas_pseries_mutex);
		vas_user_win_add_mm_context(&txwin->vas_win.task_ref);
		return &txwin->vas_win;
@@ -433,6 +448,12 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags,
	 */
	free_irq_setup(txwin);
	h_deallocate_vas_window(txwin->vas_win.winid);
	/*
	 * Hold mutex and reduce nr_open_wins_progress counter.
	 */
	mutex_lock(&vas_pseries_mutex);
	caps->nr_open_wins_progress--;
	mutex_unlock(&vas_pseries_mutex);
out:
	atomic_dec(&cop_feat_caps->nr_used_credits);
	kfree(txwin);
@@ -937,14 +958,14 @@ int vas_migration_handler(int action)
	struct vas_caps *vcaps;
	int i, rc = 0;

	pr_info("VAS migration event %d\n", action);

	/*
	 * NX-GZIP is not enabled. Nothing to do for migration.
	 */
	if (!copypaste_feat)
		return rc;

	mutex_lock(&vas_pseries_mutex);

	if (action == VAS_SUSPEND)
		migration_in_progress = true;
	else
@@ -990,12 +1011,27 @@ int vas_migration_handler(int action)

		switch (action) {
		case VAS_SUSPEND:
			mutex_lock(&vas_pseries_mutex);
			rc = reconfig_close_windows(vcaps, vcaps->nr_open_windows,
							true);
			/*
			 * Windows are included in the list after successful
			 * open. So wait for closing these in-progress open
			 * windows in vas_allocate_window() which will be
			 * done if the migration_in_progress is set.
			 */
			while (vcaps->nr_open_wins_progress) {
				mutex_unlock(&vas_pseries_mutex);
				msleep(10);
				mutex_lock(&vas_pseries_mutex);
			}
			mutex_unlock(&vas_pseries_mutex);
			break;
		case VAS_RESUME:
			mutex_lock(&vas_pseries_mutex);
			atomic_set(&caps->nr_total_credits, new_nr_creds);
			rc = reconfig_open_windows(vcaps, new_nr_creds, true);
			mutex_unlock(&vas_pseries_mutex);
			break;
		default:
			/* should not happen */
@@ -1011,8 +1047,9 @@ int vas_migration_handler(int action)
			goto out;
	}

	pr_info("VAS migration event (%d) successful\n", action);

out:
	mutex_unlock(&vas_pseries_mutex);
	return rc;
}

+2 −0
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ struct vas_cop_feat_caps {
struct vas_caps {
	struct vas_cop_feat_caps caps;
	struct list_head list;	/* List of open windows */
	int nr_open_wins_progress;	/* Number of open windows in */
					/* progress. Used in migration */
	int nr_close_wins;	/* closed windows in the hypervisor for DLPAR */
	int nr_open_windows;	/* Number of successful open windows */
	u8 feat;		/* Feature type */