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

Commit 42cd0a89 authored by Arun Menon's avatar Arun Menon
Browse files

msm: vidc: Allocate memory for response handler in probe



The response handler requires 95 KB of memory to handle
the firmware responses. This memory is allocated every
time the video driver downloads the firmware image.
If the device is running for a long time and we hit
firmware errors, then the firmware will be downloaded
several times. During this time, some video sessions
can fail because kmalloc might fail to allocate 95 KB
of contiguous memory, if the system memory is fragmented.
To overcome this problem, allocate the response handler
memory early on during probe, when the system memory is
still unfragmented.

Change-Id: I6c56eae75dca5c13c31eb1bd075f8903b236259a
Signed-off-by: default avatarArun Menon <avmenon@codeaurora.org>
parent 61a16a5e
Loading
Loading
Loading
Loading
+18 −23
Original line number Diff line number Diff line
@@ -3801,19 +3801,8 @@ static int __init_resources(struct venus_hfi_device *device,
		goto err_init_bus;
	}

	device->response_pkt = kmalloc_array(max_packets,
				sizeof(*device->response_pkt), GFP_TEMPORARY);

	if (!device->response_pkt) {
		dprintk(VIDC_ERR, "Failed to allocate resp_packets\n");
		rc = -ENOMEM;
		goto err_malloc;
	}

	return rc;

err_malloc:
	__deinit_bus(device);
err_init_bus:
	__deinit_clocks(device);
err_init_clocks:
@@ -3826,8 +3815,6 @@ static void __deinit_resources(struct venus_hfi_device *device)
	__deinit_bus(device);
	__deinit_clocks(device);
	__deinit_regulators(device);
	kfree(device->response_pkt);
	device->response_pkt = NULL;
}

static int __protect_cp_mem(struct venus_hfi_device *device)
@@ -4425,12 +4412,19 @@ static struct venus_hfi_device *__add_device(u32 device_id,
			kzalloc(sizeof(struct venus_hfi_device), GFP_KERNEL);
	if (!hdevice) {
		dprintk(VIDC_ERR, "failed to allocate new device\n");
		goto err_alloc;
		goto exit;
	}

	hdevice->response_pkt = kmalloc_array(max_packets,
				sizeof(*hdevice->response_pkt), GFP_TEMPORARY);
	if (!hdevice->response_pkt) {
		dprintk(VIDC_ERR, "failed to allocate response_pkt\n");
		goto err_cleanup;
	}

	rc = __init_regs_and_interrupts(hdevice, res);
	if (rc)
		goto err_init_regs;
		goto err_cleanup;

	hdevice->res = res;
	hdevice->device_id = device_id;
@@ -4440,17 +4434,16 @@ static struct venus_hfi_device *__add_device(u32 device_id,
		"msm_vidc_workerq_venus");
	if (!hdevice->vidc_workq) {
		dprintk(VIDC_ERR, ": create vidc workq failed\n");
		goto error_createq;
		goto err_cleanup;
	}

	hdevice->venus_pm_workq = create_singlethread_workqueue(
			"pm_workerq_venus");
	if (!hdevice->venus_pm_workq) {
		dprintk(VIDC_ERR, ": create pm workq failed\n");
		goto error_createq_pm;
		goto err_cleanup;
	}


	if (!hal_ctxt.dev_count)
		INIT_LIST_HEAD(&hal_ctxt.dev_head);

@@ -4461,12 +4454,13 @@ static struct venus_hfi_device *__add_device(u32 device_id,
	hal_ctxt.dev_count++;

	return hdevice;
error_createq_pm:

err_cleanup:
	if (hdevice->vidc_workq)
		destroy_workqueue(hdevice->vidc_workq);
error_createq:
err_init_regs:
	kfree(hdevice->response_pkt);
	kfree(hdevice);
err_alloc:
exit:
	return NULL;
}

@@ -4504,6 +4498,7 @@ void venus_hfi_delete_device(void *device)
			free_irq(dev->hal_data->irq, close);
			iounmap(dev->hal_data->register_base);
			kfree(close->hal_data);
			kfree(close->response_pkt);
			kfree(close);
			break;
		}