net: brcmfmac: Convey allocation mode as argument
The usage of in_interrupt() in drivers is phased out and Linus clearly requested that code which changes behaviour depending on context should either be seperated or the context be conveyed in an argument passed by the caller, which usually knows the context. brcmf_fweh_process_event() uses in_interrupt() to select the allocation mode GFP_KERNEL/GFP_ATOMIC. Aside of the above reasons this check is incomplete as it cannot detect contexts which just have preemption or interrupts disabled. All callchains leading to brcmf_fweh_process_event() can clearly identify the calling context. Convey a 'gfp' argument through the callchains and let the callers hand in the appropriate GFP mode. This has also the advantage that any change of execution context or preemption/interrupt state in these callchains will be detected by the memory allocator for all GFP_KERNEL allocations. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>zero-sugar-mainline-defconfig
parent
687006e20c
commit
c597ede403
|
@ -513,10 +513,12 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event,
|
|||
brcmf_proto_rxreorder(ifp, skb, inirq);
|
||||
} else {
|
||||
/* Process special event packets */
|
||||
if (handle_event)
|
||||
brcmf_fweh_process_skb(ifp->drvr, skb,
|
||||
BCMILCP_SUBTYPE_VENDOR_LONG);
|
||||
if (handle_event) {
|
||||
gfp_t gfp = inirq ? GFP_ATOMIC : GFP_KERNEL;
|
||||
|
||||
brcmf_fweh_process_skb(ifp->drvr, skb,
|
||||
BCMILCP_SUBTYPE_VENDOR_LONG, gfp);
|
||||
}
|
||||
brcmf_netif_rx(ifp, skb, inirq);
|
||||
}
|
||||
}
|
||||
|
@ -532,7 +534,7 @@ void brcmf_rx_event(struct device *dev, struct sk_buff *skb)
|
|||
if (brcmf_rx_hdrpull(drvr, skb, &ifp))
|
||||
return;
|
||||
|
||||
brcmf_fweh_process_skb(ifp->drvr, skb, 0);
|
||||
brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -388,12 +388,11 @@ int brcmf_fweh_activate_events(struct brcmf_if *ifp)
|
|||
*/
|
||||
void brcmf_fweh_process_event(struct brcmf_pub *drvr,
|
||||
struct brcmf_event *event_packet,
|
||||
u32 packet_len)
|
||||
u32 packet_len, gfp_t gfp)
|
||||
{
|
||||
enum brcmf_fweh_event_code code;
|
||||
struct brcmf_fweh_info *fweh = &drvr->fweh;
|
||||
struct brcmf_fweh_queue_item *event;
|
||||
gfp_t alloc_flag = GFP_KERNEL;
|
||||
void *data;
|
||||
u32 datalen;
|
||||
|
||||
|
@ -412,10 +411,7 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
|
|||
datalen + sizeof(*event_packet) > packet_len)
|
||||
return;
|
||||
|
||||
if (in_interrupt())
|
||||
alloc_flag = GFP_ATOMIC;
|
||||
|
||||
event = kzalloc(sizeof(*event) + datalen, alloc_flag);
|
||||
event = kzalloc(sizeof(*event) + datalen, gfp);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
|
|
|
@ -319,11 +319,12 @@ void brcmf_fweh_unregister(struct brcmf_pub *drvr,
|
|||
int brcmf_fweh_activate_events(struct brcmf_if *ifp);
|
||||
void brcmf_fweh_process_event(struct brcmf_pub *drvr,
|
||||
struct brcmf_event *event_packet,
|
||||
u32 packet_len);
|
||||
u32 packet_len, gfp_t gfp);
|
||||
void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
|
||||
|
||||
static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
|
||||
struct sk_buff *skb, u16 stype)
|
||||
struct sk_buff *skb, u16 stype,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct brcmf_event *event_packet;
|
||||
u16 subtype, usr_stype;
|
||||
|
@ -354,7 +355,7 @@ static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
|
|||
if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT)
|
||||
return;
|
||||
|
||||
brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN);
|
||||
brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN, gfp);
|
||||
}
|
||||
|
||||
#endif /* FWEH_H_ */
|
||||
|
|
|
@ -1129,7 +1129,7 @@ static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf)
|
|||
|
||||
skb->protocol = eth_type_trans(skb, ifp->ndev);
|
||||
|
||||
brcmf_fweh_process_skb(ifp->drvr, skb, 0);
|
||||
brcmf_fweh_process_skb(ifp->drvr, skb, 0, GFP_KERNEL);
|
||||
|
||||
exit:
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
|
|
Loading…
Reference in New Issue