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

Commit ec60beeb authored by Michael Ellerman's avatar Michael Ellerman Committed by Jeff Garzik
Browse files

[PATCH] iseries_veth: Make init_connection() & destroy_connection() symmetrical



This patch makes veth_init_connection() and veth_destroy_connection()
symmetrical in that they allocate/deallocate the same data.

Currently if there's an error while initialising connections (ie. ENOMEM)
we call veth_module_cleanup(), however this will oops because we call
driver_unregister() before we've called driver_register(). I've never seen
this actually happen though.

So instead we explicitly call veth_destroy_connection() for each connection,
any that have been set up will be deallocated.

We also fix a potential leak if vio_register_driver() fails.

Signed-off-by: default avatarMichael Ellerman <michael@ellerman.id.au>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent cbf9074c
Loading
Loading
Loading
Loading
+22 −13
Original line number Diff line number Diff line
@@ -683,6 +683,14 @@ static void veth_stop_connection(u8 rlp)

	/* Wait for the state machine to run. */
	flush_scheduled_work();
}

static void veth_destroy_connection(u8 rlp)
{
	struct veth_lpar_connection *cnx = veth_cnx[rlp];

	if (! cnx)
		return;

	if (cnx->num_events > 0)
		mf_deallocate_lp_events(cnx->remote_lp,
@@ -694,14 +702,6 @@ static void veth_stop_connection(u8 rlp)
				      HvLpEvent_Type_VirtualLan,
				      cnx->num_ack_events,
				      NULL, NULL);
}

static void veth_destroy_connection(u8 rlp)
{
	struct veth_lpar_connection *cnx = veth_cnx[rlp];

	if (! cnx)
		return;

	kfree(cnx->msgs);
	kfree(cnx);
@@ -1441,15 +1441,24 @@ int __init veth_module_init(void)

	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
		rc = veth_init_connection(i);
		if (rc != 0) {
			veth_module_cleanup();
			return rc;
		}
		if (rc != 0)
			goto error;
	}

	HvLpEvent_registerHandler(HvLpEvent_Type_VirtualLan,
				  &veth_handle_event);

	return vio_register_driver(&veth_driver);
	rc = vio_register_driver(&veth_driver);
	if (rc != 0)
		goto error;

	return 0;

error:
	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
		veth_destroy_connection(i);
	}

	return rc;
}
module_init(veth_module_init);