Commit b8fa3e90 authored by Halil Pasic's avatar Halil Pasic Committed by Alexander Gordeev
Browse files

s390/cio: make sch->lock spinlock pointer a member



The lock member of struct subchannel used to be a spinlock, but became
a pointer to a spinlock with commit 2ec22984 ("[S390] subchannel
lock conversion."). This might have been justified back then, but with
the current state of affairs, there is no reason to manage a separate
spinlock object.

Let's simplify things and pull the spinlock back into struct subchannel.

Signed-off-by: default avatarHalil Pasic <pasic@linux.ibm.com>
Reviewed-by: default avatarVineeth Vijayan <vneethv@linux.ibm.com>
Link: https://lore.kernel.org/r/20231101115751.2308307-1-pasic@linux.ibm.com


Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 7fe228e1
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -219,16 +219,16 @@ EXPORT_SYMBOL_GPL(chsc_sadc);

static int s390_subchannel_remove_chpid(struct subchannel *sch, void *data)
{
	spin_lock_irq(sch->lock);
	spin_lock_irq(&sch->lock);
	if (sch->driver && sch->driver->chp_event)
		if (sch->driver->chp_event(sch, data, CHP_OFFLINE) != 0)
			goto out_unreg;
	spin_unlock_irq(sch->lock);
	spin_unlock_irq(&sch->lock);
	return 0;

out_unreg:
	sch->lpm = 0;
	spin_unlock_irq(sch->lock);
	spin_unlock_irq(&sch->lock);
	css_schedule_eval(sch->schid);
	return 0;
}
@@ -258,10 +258,10 @@ void chsc_chp_offline(struct chp_id chpid)

static int __s390_process_res_acc(struct subchannel *sch, void *data)
{
	spin_lock_irq(sch->lock);
	spin_lock_irq(&sch->lock);
	if (sch->driver && sch->driver->chp_event)
		sch->driver->chp_event(sch, data, CHP_ONLINE);
	spin_unlock_irq(sch->lock);
	spin_unlock_irq(&sch->lock);

	return 0;
}
@@ -292,10 +292,10 @@ static void s390_process_res_acc(struct chp_link *link)

static int process_fces_event(struct subchannel *sch, void *data)
{
	spin_lock_irq(sch->lock);
	spin_lock_irq(&sch->lock);
	if (sch->driver && sch->driver->chp_event)
		sch->driver->chp_event(sch, data, CHP_FCES_EVENT);
	spin_unlock_irq(sch->lock);
	spin_unlock_irq(&sch->lock);
	return 0;
}

@@ -769,11 +769,11 @@ static void __s390_subchannel_vary_chpid(struct subchannel *sch,

	memset(&link, 0, sizeof(struct chp_link));
	link.chpid = chpid;
	spin_lock_irqsave(sch->lock, flags);
	spin_lock_irqsave(&sch->lock, flags);
	if (sch->driver && sch->driver->chp_event)
		sch->driver->chp_event(sch, &link,
				       on ? CHP_VARY_ON : CHP_VARY_OFF);
	spin_unlock_irqrestore(sch->lock, flags);
	spin_unlock_irqrestore(&sch->lock, flags);
}

static int s390_subchannel_vary_chpid_off(struct subchannel *sch, void *data)
+3 −3
Original line number Diff line number Diff line
@@ -211,10 +211,10 @@ static int chsc_async(struct chsc_async_area *chsc_area,

	chsc_area->header.key = PAGE_DEFAULT_KEY >> 4;
	while ((sch = chsc_get_next_subchannel(sch))) {
		spin_lock(sch->lock);
		spin_lock(&sch->lock);
		private = dev_get_drvdata(&sch->dev);
		if (private->request) {
			spin_unlock(sch->lock);
			spin_unlock(&sch->lock);
			ret = -EBUSY;
			continue;
		}
@@ -239,7 +239,7 @@ static int chsc_async(struct chsc_async_area *chsc_area,
		default:
			ret = -ENODEV;
		}
		spin_unlock(sch->lock);
		spin_unlock(&sch->lock);
		CHSC_MSG(2, "chsc on 0.%x.%04x returned cc=%d\n",
			 sch->schid.ssid, sch->schid.sch_no, cc);
		if (ret == -EINPROGRESS)
+3 −3
Original line number Diff line number Diff line
@@ -546,7 +546,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
		return IRQ_HANDLED;
	}
	sch = phys_to_virt(tpi_info->intparm);
	spin_lock(sch->lock);
	spin_lock(&sch->lock);
	/* Store interrupt response block to lowcore. */
	if (tsch(tpi_info->schid, irb) == 0) {
		/* Keep subchannel information word up to date. */
@@ -558,7 +558,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
			inc_irq_stat(IRQIO_CIO);
	} else
		inc_irq_stat(IRQIO_CIO);
	spin_unlock(sch->lock);
	spin_unlock(&sch->lock);

	return IRQ_HANDLED;
}
@@ -663,7 +663,7 @@ struct subchannel *cio_probe_console(void)
	if (IS_ERR(sch))
		return sch;

	lockdep_set_class(sch->lock, &console_sch_key);
	lockdep_set_class(&sch->lock, &console_sch_key);
	isc_register(CONSOLE_ISC);
	sch->config.isc = CONSOLE_ISC;
	sch->config.intparm = (u32)virt_to_phys(sch);
+1 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ enum sch_todo {
/* subchannel data structure used by I/O subroutines */
struct subchannel {
	struct subchannel_id schid;
	spinlock_t *lock;	/* subchannel lock */
	spinlock_t lock;	/* subchannel lock */
	struct mutex reg_mutex;
	enum {
		SUBCHANNEL_TYPE_IO = 0,
+10 −26
Original line number Diff line number Diff line
@@ -148,16 +148,10 @@ int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),

static void css_sch_todo(struct work_struct *work);

static int css_sch_create_locks(struct subchannel *sch)
static void css_sch_create_locks(struct subchannel *sch)
{
	sch->lock = kmalloc(sizeof(*sch->lock), GFP_KERNEL);
	if (!sch->lock)
		return -ENOMEM;

	spin_lock_init(sch->lock);
	spin_lock_init(&sch->lock);
	mutex_init(&sch->reg_mutex);

	return 0;
}

static void css_subchannel_release(struct device *dev)
@@ -167,7 +161,6 @@ static void css_subchannel_release(struct device *dev)
	sch->config.intparm = 0;
	cio_commit_config(sch);
	kfree(sch->driver_override);
	kfree(sch->lock);
	kfree(sch);
}

@@ -219,9 +212,7 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid,
	sch->schib = *schib;
	sch->st = schib->pmcw.st;

	ret = css_sch_create_locks(sch);
	if (ret)
		goto err;
	css_sch_create_locks(sch);

	INIT_WORK(&sch->todo_work, css_sch_todo);
	sch->dev.release = &css_subchannel_release;
@@ -233,19 +224,17 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid,
	 */
	ret = dma_set_coherent_mask(&sch->dev, DMA_BIT_MASK(31));
	if (ret)
		goto err_lock;
		goto err;
	/*
	 * But we don't have such restrictions imposed on the stuff that
	 * is handled by the streaming API.
	 */
	ret = dma_set_mask(&sch->dev, DMA_BIT_MASK(64));
	if (ret)
		goto err_lock;
		goto err;

	return sch;

err_lock:
	kfree(sch->lock);
err:
	kfree(sch);
	return ERR_PTR(ret);
@@ -604,12 +593,12 @@ static void css_sch_todo(struct work_struct *work)

	sch = container_of(work, struct subchannel, todo_work);
	/* Find out todo. */
	spin_lock_irq(sch->lock);
	spin_lock_irq(&sch->lock);
	todo = sch->todo;
	CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid,
		      sch->schid.sch_no, todo);
	sch->todo = SCH_TODO_NOTHING;
	spin_unlock_irq(sch->lock);
	spin_unlock_irq(&sch->lock);
	/* Perform todo. */
	switch (todo) {
	case SCH_TODO_NOTHING:
@@ -617,9 +606,9 @@ static void css_sch_todo(struct work_struct *work)
	case SCH_TODO_EVAL:
		ret = css_evaluate_known_subchannel(sch, 1);
		if (ret == -EAGAIN) {
			spin_lock_irq(sch->lock);
			spin_lock_irq(&sch->lock);
			css_sched_sch_todo(sch, todo);
			spin_unlock_irq(sch->lock);
			spin_unlock_irq(&sch->lock);
		}
		break;
	case SCH_TODO_UNREG:
@@ -1028,12 +1017,7 @@ static int __init setup_css(int nr)
	css->pseudo_subchannel->dev.parent = &css->device;
	css->pseudo_subchannel->dev.release = css_subchannel_release;
	mutex_init(&css->pseudo_subchannel->reg_mutex);
	ret = css_sch_create_locks(css->pseudo_subchannel);
	if (ret) {
		kfree(css->pseudo_subchannel);
		device_unregister(&css->device);
		goto out_err;
	}
	css_sch_create_locks(css->pseudo_subchannel);

	dev_set_name(&css->pseudo_subchannel->dev, "defunct");
	ret = device_register(&css->pseudo_subchannel->dev);
Loading