mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
nvadsp: adspff: fix issues with kthread impl
- Implement file list rather than fixed length array
- Fix issues related to file mode handling
- Change file not found validation with respect to commit c136844cd414
("nvadsp: adspff: use kthread to schedule file io")
Bug 2538512
Change-Id: I1cd8fa065887effa6073d963df62f6e1bb877a1d
Signed-off-by: Niranjan Dighe <ndighe@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2102696
(cherry picked from commit ea7d4ea78a22b7d8675966f2b2f85343c488d059)
Reviewed-on: https://git-master.nvidia.com/r/2150780
Tested-by: Hariharan Sivaraman <hariharans@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Nitin Pai <npai@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Laxman Dewangan
parent
b82520e6d3
commit
8916271137
@@ -26,6 +26,7 @@
|
|||||||
#include <linux/semaphore.h>
|
#include <linux/semaphore.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
|
||||||
#include <linux/tegra_nvadsp.h>
|
#include <linux/tegra_nvadsp.h>
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@
|
|||||||
#include "dev.h"
|
#include "dev.h"
|
||||||
|
|
||||||
|
|
||||||
#define ADSPFF_MAX_OPEN_FILES (4)
|
#define ADSPFF_MAX_OPEN_FILES (32)
|
||||||
|
|
||||||
struct file_struct {
|
struct file_struct {
|
||||||
struct file *fp;
|
struct file *fp;
|
||||||
@@ -41,11 +42,12 @@ struct file_struct {
|
|||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
unsigned long long wr_offset;
|
unsigned long long wr_offset;
|
||||||
unsigned long long rd_offset;
|
unsigned long long rd_offset;
|
||||||
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct file_struct adspff_open_files[ADSPFF_MAX_OPEN_FILES];
|
static struct list_head file_list;
|
||||||
|
|
||||||
static spinlock_t adspff_lock;
|
static spinlock_t adspff_lock;
|
||||||
|
static int open_count;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Kernel file functions
|
* Kernel file functions
|
||||||
@@ -162,31 +164,40 @@ void set_flags(union adspff_message_t *m, unsigned int *flags)
|
|||||||
/*
|
/*
|
||||||
* checks if file is already opened
|
* checks if file is already opened
|
||||||
* if yes, then returns the struct file_struct for the file
|
* if yes, then returns the struct file_struct for the file
|
||||||
* if no, thgen returns first available struct file_struct
|
* if no, then allocates a file_struct and adds to the list
|
||||||
* if ADSPFF_MAX_OPEN_FILES alreadu open, returns NULL
|
* and returns the pointer to the newly allocated file_struct
|
||||||
|
* if ADSPFF_MAX_OPEN_FILES already open, returns NULL
|
||||||
*/
|
*/
|
||||||
static struct file_struct *check_file_opened(const char *path)
|
static struct file_struct *check_file_opened(const char *path)
|
||||||
{
|
{
|
||||||
struct file_struct *file;
|
struct file_struct *file = NULL;
|
||||||
int idx;
|
struct list_head *pos;
|
||||||
|
|
||||||
/* assuming files opened by ADSP will
|
/* assuming files opened by ADSP will
|
||||||
* never be actually closed in kernel
|
* never be actually closed in kernel
|
||||||
*/
|
*/
|
||||||
for (idx = 0; idx < ADSPFF_MAX_OPEN_FILES; idx++) {
|
list_for_each(pos, &file_list) {
|
||||||
file = &adspff_open_files[idx];
|
file = list_entry(pos, struct file_struct, list);
|
||||||
if (!file->fp)
|
if (!file->fp)
|
||||||
break;
|
break;
|
||||||
if (!strncmp(path, file->file_name,
|
if (!strncmp(path, file->file_name,
|
||||||
ADSPFF_MAX_FILENAME_SIZE)) {
|
ADSPFF_MAX_FILENAME_SIZE)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx == ADSPFF_MAX_OPEN_FILES) {
|
if (file != NULL)
|
||||||
|
return file;
|
||||||
|
|
||||||
|
if (open_count == ADSPFF_MAX_OPEN_FILES) {
|
||||||
pr_err("adspff: %d files already opened\n",
|
pr_err("adspff: %d files already opened\n",
|
||||||
ADSPFF_MAX_OPEN_FILES);
|
ADSPFF_MAX_OPEN_FILES);
|
||||||
file = NULL;
|
file = NULL;
|
||||||
|
} else {
|
||||||
|
file = kzalloc(sizeof(*file), GFP_KERNEL);
|
||||||
|
open_count++;
|
||||||
|
list_add_tail(&file->list, &file_list);
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@@ -242,8 +253,7 @@ void adspff_fopen(void)
|
|||||||
file->flags = flags;
|
file->flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(file->fp)) {
|
if (file && !file->fp) {
|
||||||
kfree(file);
|
|
||||||
file = NULL;
|
file = NULL;
|
||||||
pr_err("File not found - %s\n",
|
pr_err("File not found - %s\n",
|
||||||
(const char *) message->msg.payload.fopen_msg.fname);
|
(const char *) message->msg.payload.fopen_msg.fname);
|
||||||
@@ -256,6 +266,12 @@ void adspff_fopen(void)
|
|||||||
(msgq_message_t *)msg_recv);
|
(msgq_message_t *)msg_recv);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("fopen Enqueue failed %d.", ret);
|
pr_err("fopen Enqueue failed %d.", ret);
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
file_close(file->fp);
|
||||||
|
file->fp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
kfree(message);
|
kfree(message);
|
||||||
kfree(msg_recv);
|
kfree(msg_recv);
|
||||||
return;
|
return;
|
||||||
@@ -269,7 +285,7 @@ void adspff_fopen(void)
|
|||||||
|
|
||||||
static inline unsigned int is_read_file(struct file_struct *file)
|
static inline unsigned int is_read_file(struct file_struct *file)
|
||||||
{
|
{
|
||||||
return file->flags & (O_RDONLY | O_RDWR);
|
return ((!file->flags) || (file->flags & O_RDWR));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int is_write_file(struct file_struct *file)
|
static inline unsigned int is_write_file(struct file_struct *file)
|
||||||
@@ -585,17 +601,20 @@ static int adspff_msg_handler(uint32_t msg, void *data)
|
|||||||
|
|
||||||
static int adspff_set(void *data, u64 val)
|
static int adspff_set(void *data, u64 val)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
struct file_struct *file;
|
struct file_struct *file;
|
||||||
|
struct list_head *pos, *n;
|
||||||
|
|
||||||
if (val != 1)
|
if (val != 1)
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < ADSPFF_MAX_OPEN_FILES; i++) {
|
list_for_each_safe(pos, n, &file_list) {
|
||||||
file = &adspff_open_files[i];
|
file = list_entry(pos, struct file_struct, list);
|
||||||
|
list_del(pos);
|
||||||
if (file->fp)
|
if (file->fp)
|
||||||
file_close(file->fp);
|
file_close(file->fp);
|
||||||
|
kfree(file);
|
||||||
}
|
}
|
||||||
memset(adspff_open_files, 0, sizeof(adspff_open_files));
|
|
||||||
|
open_count = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -650,13 +669,12 @@ int adspff_init(struct platform_device *pdev)
|
|||||||
|
|
||||||
spin_lock_init(&adspff_lock);
|
spin_lock_init(&adspff_lock);
|
||||||
|
|
||||||
memset(&adspff_open_files, 0, sizeof(adspff_open_files));
|
|
||||||
|
|
||||||
ret = adspff_debugfs_init(drv);
|
ret = adspff_debugfs_init(drv);
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_warn("adspff: failed to create debugfs entry\n");
|
pr_warn("adspff: failed to create debugfs entry\n");
|
||||||
|
|
||||||
INIT_LIST_HEAD(&adspff_kthread_msgq_head);
|
INIT_LIST_HEAD(&adspff_kthread_msgq_head);
|
||||||
|
INIT_LIST_HEAD(&file_list);
|
||||||
|
|
||||||
adspff_kthread = kthread_create(adspff_kthread_fn,
|
adspff_kthread = kthread_create(adspff_kthread_fn,
|
||||||
NULL, "adspp_kthread");
|
NULL, "adspp_kthread");
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ enum adspff_mbx_cmd {
|
|||||||
/* supported message payloads */
|
/* supported message payloads */
|
||||||
struct fopen_msg_t {
|
struct fopen_msg_t {
|
||||||
uint8_t fname[ADSPFF_MAX_FILENAME_SIZE];
|
uint8_t fname[ADSPFF_MAX_FILENAME_SIZE];
|
||||||
uint8_t modes[2];
|
uint8_t modes[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fwrite_msg_t {
|
struct fwrite_msg_t {
|
||||||
|
|||||||
Reference in New Issue
Block a user