if (mxlogger && mxlogger->mx)
mif = scsc_mx_get_mif_abs(mxlogger->mx);
else
- return -EIO;
+ /* Return 0 as 'success' to continue the collection of other chunks */
+ return 0;
mutex_lock(&mxlogger->lock);
+ if (mxlogger->initialized == false) {
+ SCSC_TAG_ERR(MXMAN, "MXLOGGER not initialized\n");
+ mutex_unlock(&mxlogger->lock);
+ return 0;
+ }
+
if (collect_client->type == SCSC_LOG_CHUNK_SYNC)
i = MXLOGGER_SYNC;
else if (collect_client->type == SCSC_LOG_CHUNK_IMP)
}
mutex_unlock(&mxlogger->lock);
- return ret;
+ return 0;
}
static int mxlogger_collect_end(struct scsc_log_collector_client *collect_client)
struct mxlogger_node *mn, *next;
bool match = false;
+ /* Run deregistration before adquiring the mxlogger lock to avoid
+ * deadlock with log_collector.
+ */
+#ifdef CONFIG_SCSC_LOG_COLLECTION
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_sync);
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_imp);
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_common);
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_bt);
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_wlan);
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_radio);
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_mxl);
+ scsc_log_collector_unregister_client(&mxlogger_collect_client_udi);
+#endif
mutex_lock(&mxlogger->lock);
mxlogger->initialized = false;
mxlogger_to_host(mxlogger);
if (match == false)
SCSC_TAG_ERR(MXMAN, "FATAL, no match for given scsc_mif_abs\n");
-#ifdef CONFIG_SCSC_LOG_COLLECTION
- scsc_log_collector_unregister_client(&mxlogger_collect_client_sync);
- scsc_log_collector_unregister_client(&mxlogger_collect_client_imp);
- scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_common);
- scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_bt);
- scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_wlan);
- scsc_log_collector_unregister_client(&mxlogger_collect_client_rsv_radio);
- scsc_log_collector_unregister_client(&mxlogger_collect_client_mxl);
- scsc_log_collector_unregister_client(&mxlogger_collect_client_udi);
-#endif
mutex_unlock(&mxlogger->lock);
}
mutex_lock(&mxlogger->lock);
if (mxlogger->observers == 0) {
- SCSC_TAG_INFO(MXMAN, "Incorrect number of observers \n");
+ SCSC_TAG_INFO(MXMAN, "Incorrect number of observers\n");
mutex_unlock(&mxlogger->lock);
return -EIO;
}
}
/* Global observer are not associated to any [mx] mxlogger instance. So it registers as
- * an observer to all the [mx] mxlogger instances. */
+ * an observer to all the [mx] mxlogger instances.
+ */
int mxlogger_register_global_observer(char *name)
{
struct mxlogger_node *mn, *next;
loff_t pos;
bool in_collection;
char fapi_ver[SCSC_LOG_FAPI_VERSION_SIZE];
- struct mutex log_mutex;
- struct mutex collection_mutex;
struct workqueue_struct *collection_workq;
struct work_struct collect_work;
enum scsc_log_reason collect_reason;
} log_status;
+static DEFINE_MUTEX(log_mutex);
+
static void collection_worker(struct work_struct *work)
{
struct scsc_log_status *ls;
{
pr_info("Log Collector Init\n");
- mutex_init(&log_status.log_mutex);
- mutex_init(&log_status.collection_mutex);
log_status.in_collection = false;
log_status.collection_workq = create_workqueue("log_collector");
if (log_status.collection_workq)
return -EIO;
}
+ mutex_lock(&log_mutex);
lc = kzalloc(sizeof(*lc), GFP_KERNEL);
- if (!lc)
+ if (!lc) {
+ mutex_unlock(&log_mutex);
return -ENOMEM;
+ }
lc->collect_client = collect_client;
list_add_tail(&lc->list, &scsc_log_collector_list.list);
list_sort(NULL, &scsc_log_collector_list.list, scsc_log_collector_compare);
pr_info("Registered client: %s\n", collect_client->name);
+ mutex_unlock(&log_mutex);
return 0;
}
EXPORT_SYMBOL(scsc_log_collector_register_client);
bool match = false;
/* block any attempt of unregistering while a collection is in progres */
- mutex_lock(&log_status.log_mutex);
+ mutex_lock(&log_mutex);
list_for_each_entry_safe(lc, next, &scsc_log_collector_list.list, list) {
if (lc->collect_client == collect_client) {
match = true;
pr_err("FATAL, no match for given scsc_log_collector_client\n");
pr_info("Unregistered client: %s\n", collect_client->name);
- mutex_unlock(&log_status.log_mutex);
+ mutex_unlock(&log_mutex);
return 0;
}
struct scsc_log_chunk_header chk_header;
u8 j;
- mutex_lock(&log_status.log_mutex);
+ mutex_lock(&log_mutex);
pr_info("Log collection to file triggered\n");
pr_info("File %s collection end. Took: %lld\n", memdump_path, ktime_to_ns(ktime_sub(ktime_get(), start)));
- mutex_unlock(&log_status.log_mutex);
+ mutex_unlock(&log_mutex);
return ret;
}
{
int ret;
- mutex_lock(&log_status.collection_mutex);
if (collect_to_ram)
ret = __scsc_log_collector_collect_to_ram(reason);
else
ret = __scsc_log_collector_collect_to_file(reason);
- mutex_unlock(&log_status.collection_mutex);
return ret;
}
service = sdev->service;
#ifdef CONFIG_SCSC_LOG_COLLECTION
- mutex_lock(&hip->hip_priv->in_collection);
hip4_collect_hcf_client.prv = NULL;
+ /* Unregister outside the in_collection_lock to avoid deadlock */
scsc_log_collector_unregister_client(&hip4_collect_hcf_client);
+ mutex_lock(&hip->hip_priv->in_collection);
if (hip->hip_priv->mib_collect) {
hip->hip_priv->mib_sz = 0;
vfree(hip->hip_priv->mib_collect);