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

Commit c6c0a866 authored by Mayank Rana's avatar Mayank Rana Committed by Gerrit - the friendly Code Review server
Browse files

USB: f_fs: Add memory barrier before atomic operations



In few instances, it is observed that multiple adbd instances are
running on device causing condition BUG_ON(ffs->gadget) to be true.
ffs->opened and ffs->ref atomic variables are used here to make
decision for checking ffs->gadget. These atomic variable operations
requires expilict memory barrier to make sure that update to
ffs->gadget is visible to other CPUs before updated atomic variable
based value is seen.

CRs-Fixed: 793733
Change-Id: I3c846eb6bbb53663892e05d51ebac8439aac957a
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent d22f4f5f
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -699,6 +699,7 @@ static int ffs_ep0_open(struct inode *inode, struct file *file)
	if (unlikely(ffs->state == FFS_CLOSING))
		return -EBUSY;

	smp_mb__before_atomic();
	if (atomic_read(&ffs->opened))
		return -EBUSY;

@@ -1344,6 +1345,7 @@ static void ffs_data_get(struct ffs_data *ffs)
{
	ENTER();

	smp_mb__before_atomic();
	atomic_inc(&ffs->ref);
}

@@ -1351,6 +1353,7 @@ static void ffs_data_opened(struct ffs_data *ffs)
{
	ENTER();

	smp_mb__before_atomic();
	atomic_inc(&ffs->ref);
	atomic_inc(&ffs->opened);
}
@@ -1359,6 +1362,7 @@ static void ffs_data_put(struct ffs_data *ffs)
{
	ENTER();

	smp_mb__before_atomic();
	if (unlikely(atomic_dec_and_test(&ffs->ref))) {
		pr_info("%s(): freeing\n", __func__);
		ffs_data_clear(ffs);
@@ -1373,6 +1377,7 @@ static void ffs_data_closed(struct ffs_data *ffs)
{
	ENTER();

	smp_mb__before_atomic();
	if (atomic_dec_and_test(&ffs->opened)) {
		ffs->state = FFS_CLOSING;
		ffs_data_reset(ffs);
@@ -1416,8 +1421,8 @@ static void ffs_data_clear(struct ffs_data *ffs)

	/* Dump ffs->gadget and ffs->flags */
	if (ffs->gadget)
		pr_err("%s: ffs->gadget= %p, ffs->flags= %lu\n", __func__,
						ffs->gadget, ffs->flags);
		pr_err("%s: ffs:%p ffs->gadget= %p, ffs->flags= %lu\n",
				__func__, ffs, ffs->gadget, ffs->flags);
	BUG_ON(ffs->gadget);

	if (ffs->epfiles)