Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87dc8a01 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

s390/cio: ensure that a chpid is registered only once



Improve locking in chp_new to make sure that we don't register
the same chpid twice. Chpid registration was synchronized via
the machine check handler thread but we also have codepaths to
look for new chpids triggered independent of that thread (during
IPL or resume from hibernate).

Signed-off-by: default avatarSebastian Ott <sebott@linux.ibm.com>
Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 306d6c49
Loading
Loading
Loading
Loading
+11 −10
Original line number Diff line number Diff line
@@ -471,14 +471,17 @@ int chp_new(struct chp_id chpid)
{
	struct channel_subsystem *css = css_by_id(chpid.cssid);
	struct channel_path *chp;
	int ret;
	int ret = 0;

	mutex_lock(&css->mutex);
	if (chp_is_registered(chpid))
		return 0;
	chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL);
	if (!chp)
		return -ENOMEM;
		goto out;

	chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL);
	if (!chp) {
		ret = -ENOMEM;
		goto out;
	}
	/* fill in status, etc. */
	chp->chpid = chpid;
	chp->state = 1;
@@ -505,21 +508,20 @@ int chp_new(struct chp_id chpid)
		put_device(&chp->dev);
		goto out;
	}
	mutex_lock(&css->mutex);

	if (css->cm_enabled) {
		ret = chp_add_cmg_attr(chp);
		if (ret) {
			device_unregister(&chp->dev);
			mutex_unlock(&css->mutex);
			goto out;
		}
	}
	css->chps[chpid.id] = chp;
	mutex_unlock(&css->mutex);
	goto out;
out_free:
	kfree(chp);
out:
	mutex_unlock(&css->mutex);
	return ret;
}

@@ -585,7 +587,6 @@ static void chp_process_crw(struct crw *crw0, struct crw *crw1,
	switch (crw0->erc) {
	case CRW_ERC_IPARM: /* Path has come. */
	case CRW_ERC_INIT:
		if (!chp_is_registered(chpid))
		chp_new(chpid);
		chsc_chp_online(chpid);
		break;
+1 −2
Original line number Diff line number Diff line
@@ -244,7 +244,6 @@ static void ssd_register_chpids(struct chsc_ssd_info *ssd)
	for (i = 0; i < 8; i++) {
		mask = 0x80 >> i;
		if (ssd->path_mask & mask)
			if (!chp_is_registered(ssd->chpid[i]))
			chp_new(ssd->chpid[i]);
	}
}