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

Commit 3064ec89 authored by Tejas Prajapati's avatar Tejas Prajapati Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: reqmgr: reader writer locks to avoid memory faults



Shared memory is initialized by CRM and used by
other drivers; with CRM not active other drivers
would fail to access the shared memory if
memory manager is deinit. Reader Writer locks can
prevent the open/close/ioctl calls from other drivers
if CRM open/close is already being processed.

Issue observed with the below sequence if drivers
are opened from UMD directly without this change.
CRM Open successful,ICP open successful,
CRM close in progress, ICP open successful,
mem mgr deinit and CRM close successful,
ICP tries to access HFI memory and result in crash.

This change helps to serialze the calls and prevents
issue.

CRs-Fixed: 3019488
Change-Id: I98554f952acd8febf65cc1144150e728a874171d
Signed-off-by: default avatarTejas Prajapati <quic_tpraja@quicinc.com>
parent 0cf22593
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -60,8 +60,10 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd,


	switch (cmd) {
	switch (cmd) {
	case VIDIOC_CAM_CONTROL:
	case VIDIOC_CAM_CONTROL:
		cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);
		rc = cam_node_handle_ioctl(node,
		rc = cam_node_handle_ioctl(node,
			(struct cam_control *) arg);
			(struct cam_control *) arg);
		cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
		break;
		break;
	default:
	default:
		CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
		CAM_ERR(CAM_CORE, "Invalid command %d for %s", cmd,
+6 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -50,8 +50,11 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd,
{
{
	struct cam_fd_dev *fd_dev = &g_fd_dev;
	struct cam_fd_dev *fd_dev = &g_fd_dev;


	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);

	if (!fd_dev->probe_done) {
	if (!fd_dev->probe_done) {
		CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev);
		CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev);
		cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
		return -ENODEV;
		return -ENODEV;
	}
	}


@@ -60,6 +63,8 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd,
	CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
	CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt);
	mutex_unlock(&fd_dev->lock);
	mutex_unlock(&fd_dev->lock);


	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);

	return 0;
	return 0;
}
}


+4 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, 2021The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -82,6 +82,8 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd,
	struct cam_node *node = v4l2_get_subdevdata(sd);
	struct cam_node *node = v4l2_get_subdevdata(sd);
	int rc = 0;
	int rc = 0;


	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);

	mutex_lock(&g_icp_dev.icp_lock);
	mutex_lock(&g_icp_dev.icp_lock);
	if (g_icp_dev.open_cnt >= 1) {
	if (g_icp_dev.open_cnt >= 1) {
		CAM_ERR(CAM_ICP, "ICP subdev is already opened");
		CAM_ERR(CAM_ICP, "ICP subdev is already opened");
@@ -104,6 +106,7 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd,
	g_icp_dev.open_cnt++;
	g_icp_dev.open_cnt++;
end:
end:
	mutex_unlock(&g_icp_dev.icp_lock);
	mutex_unlock(&g_icp_dev.icp_lock);
	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);
	return rc;
	return rc;
}
}


+5 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -59,10 +59,14 @@ static const struct of_device_id cam_isp_dt_match[] = {
static int cam_isp_subdev_open(struct v4l2_subdev *sd,
static int cam_isp_subdev_open(struct v4l2_subdev *sd,
	struct v4l2_subdev_fh *fh)
	struct v4l2_subdev_fh *fh)
{
{
	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);

	mutex_lock(&g_isp_dev.isp_mutex);
	mutex_lock(&g_isp_dev.isp_mutex);
	g_isp_dev.open_cnt++;
	g_isp_dev.open_cnt++;
	mutex_unlock(&g_isp_dev.isp_mutex);
	mutex_unlock(&g_isp_dev.isp_mutex);


	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);

	return 0;
	return 0;
}
}


+4 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -57,11 +57,14 @@ static const struct of_device_id cam_jpeg_dt_match[] = {
static int cam_jpeg_subdev_open(struct v4l2_subdev *sd,
static int cam_jpeg_subdev_open(struct v4l2_subdev *sd,
	struct v4l2_subdev_fh *fh)
	struct v4l2_subdev_fh *fh)
{
{
	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK);


	mutex_lock(&g_jpeg_dev.jpeg_mutex);
	mutex_lock(&g_jpeg_dev.jpeg_mutex);
	g_jpeg_dev.open_cnt++;
	g_jpeg_dev.open_cnt++;
	mutex_unlock(&g_jpeg_dev.jpeg_mutex);
	mutex_unlock(&g_jpeg_dev.jpeg_mutex);


	cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK);

	return 0;
	return 0;
}
}


Loading