msm: rpc: Reader thread to allocate memory without holding a spinlock
RPC Router reader thread is allocating memory with GFP_KERNEL mask while
holding a spinlock. This is causing kernel BUG.
CRs-Fixed: 305570
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/smd_rpcrouter.c b/arch/arm/mach-msm/smd_rpcrouter.c
index 98c5998..93fa244 100644
--- a/arch/arm/mach-msm/smd_rpcrouter.c
+++ b/arch/arm/mach-msm/smd_rpcrouter.c
@@ -1146,6 +1146,8 @@
goto done;
}
}
+ spin_unlock(&ept->incomplete_lock);
+ spin_unlock_irqrestore(&local_endpoints_lock, flags);
/* This mid is new -- create a packet for it, and put it on
* the incomplete list if this fragment is not a last fragment,
* otherwise put it on the read queue.
@@ -1156,13 +1158,23 @@
memcpy(&pkt->hdr, &hdr, sizeof(hdr));
pkt->mid = mid;
pkt->length = frag->length;
+
+ spin_lock_irqsave(&local_endpoints_lock, flags);
+ ept = rpcrouter_lookup_local_endpoint(hdr.dst_cid);
+ if (!ept) {
+ spin_unlock_irqrestore(&local_endpoints_lock, flags);
+ DIAG("no local ept for cid %08x\n", hdr.dst_cid);
+ kfree(frag);
+ kfree(pkt);
+ goto done;
+ }
if (!PACMARK_LAST(pm)) {
+ spin_lock(&ept->incomplete_lock);
list_add_tail(&pkt->list, &ept->incomplete);
spin_unlock(&ept->incomplete_lock);
spin_unlock_irqrestore(&local_endpoints_lock, flags);
goto done;
}
- spin_unlock(&ept->incomplete_lock);
packet_complete:
spin_lock(&ept->read_q_lock);