tipc: allocate user memory with GFP_KERNEL flag
Until now, we allocate memory always with GFP_ATOMIC flag. When the system is under memory pressure and a user tries to send, the send fails due to low memory. However, the user application can wait for free memory if we allocate it using GFP_KERNEL flag. In this commit, we use allocate memory with GFP_KERNEL for all user allocation. Reported-by: Rune Torgersen <runet@innovsys.com> Acked-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>zero-colors
parent
34c55cf2fc
commit
57d5f64d83
|
@ -169,7 +169,7 @@ void tipc_disc_rcv(struct net *net, struct sk_buff *skb,
|
||||||
|
|
||||||
/* Send response, if necessary */
|
/* Send response, if necessary */
|
||||||
if (respond && (mtyp == DSC_REQ_MSG)) {
|
if (respond && (mtyp == DSC_REQ_MSG)) {
|
||||||
rskb = tipc_buf_acquire(MAX_H_SIZE);
|
rskb = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
|
||||||
if (!rskb)
|
if (!rskb)
|
||||||
return;
|
return;
|
||||||
tipc_disc_init_msg(net, rskb, DSC_RESP_MSG, bearer);
|
tipc_disc_init_msg(net, rskb, DSC_RESP_MSG, bearer);
|
||||||
|
@ -278,7 +278,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b,
|
||||||
req = kmalloc(sizeof(*req), GFP_ATOMIC);
|
req = kmalloc(sizeof(*req), GFP_ATOMIC);
|
||||||
if (!req)
|
if (!req)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
req->buf = tipc_buf_acquire(MAX_H_SIZE);
|
req->buf = tipc_buf_acquire(MAX_H_SIZE, GFP_ATOMIC);
|
||||||
if (!req->buf) {
|
if (!req->buf) {
|
||||||
kfree(req);
|
kfree(req);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -1395,7 +1395,7 @@ tnl:
|
||||||
msg_set_seqno(hdr, seqno++);
|
msg_set_seqno(hdr, seqno++);
|
||||||
pktlen = msg_size(hdr);
|
pktlen = msg_size(hdr);
|
||||||
msg_set_size(&tnlhdr, pktlen + INT_H_SIZE);
|
msg_set_size(&tnlhdr, pktlen + INT_H_SIZE);
|
||||||
tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE);
|
tnlskb = tipc_buf_acquire(pktlen + INT_H_SIZE, GFP_ATOMIC);
|
||||||
if (!tnlskb) {
|
if (!tnlskb) {
|
||||||
pr_warn("%sunable to send packet\n", link_co_err);
|
pr_warn("%sunable to send packet\n", link_co_err);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -58,12 +58,12 @@ static unsigned int align(unsigned int i)
|
||||||
* NOTE: Headroom is reserved to allow prepending of a data link header.
|
* NOTE: Headroom is reserved to allow prepending of a data link header.
|
||||||
* There may also be unrequested tailroom present at the buffer's end.
|
* There may also be unrequested tailroom present at the buffer's end.
|
||||||
*/
|
*/
|
||||||
struct sk_buff *tipc_buf_acquire(u32 size)
|
struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp)
|
||||||
{
|
{
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
|
unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u;
|
||||||
|
|
||||||
skb = alloc_skb_fclone(buf_size, GFP_ATOMIC);
|
skb = alloc_skb_fclone(buf_size, gfp);
|
||||||
if (skb) {
|
if (skb) {
|
||||||
skb_reserve(skb, BUF_HEADROOM);
|
skb_reserve(skb, BUF_HEADROOM);
|
||||||
skb_put(skb, size);
|
skb_put(skb, size);
|
||||||
|
@ -95,7 +95,7 @@ struct sk_buff *tipc_msg_create(uint user, uint type,
|
||||||
struct tipc_msg *msg;
|
struct tipc_msg *msg;
|
||||||
struct sk_buff *buf;
|
struct sk_buff *buf;
|
||||||
|
|
||||||
buf = tipc_buf_acquire(hdr_sz + data_sz);
|
buf = tipc_buf_acquire(hdr_sz + data_sz, GFP_ATOMIC);
|
||||||
if (unlikely(!buf))
|
if (unlikely(!buf))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -261,7 +261,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
|
||||||
|
|
||||||
/* No fragmentation needed? */
|
/* No fragmentation needed? */
|
||||||
if (likely(msz <= pktmax)) {
|
if (likely(msz <= pktmax)) {
|
||||||
skb = tipc_buf_acquire(msz);
|
skb = tipc_buf_acquire(msz, GFP_KERNEL);
|
||||||
if (unlikely(!skb))
|
if (unlikely(!skb))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
skb_orphan(skb);
|
skb_orphan(skb);
|
||||||
|
@ -282,7 +282,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
|
||||||
msg_set_importance(&pkthdr, msg_importance(mhdr));
|
msg_set_importance(&pkthdr, msg_importance(mhdr));
|
||||||
|
|
||||||
/* Prepare first fragment */
|
/* Prepare first fragment */
|
||||||
skb = tipc_buf_acquire(pktmax);
|
skb = tipc_buf_acquire(pktmax, GFP_KERNEL);
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
skb_orphan(skb);
|
skb_orphan(skb);
|
||||||
|
@ -313,7 +313,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
|
||||||
pktsz = drem + INT_H_SIZE;
|
pktsz = drem + INT_H_SIZE;
|
||||||
else
|
else
|
||||||
pktsz = pktmax;
|
pktsz = pktmax;
|
||||||
skb = tipc_buf_acquire(pktsz);
|
skb = tipc_buf_acquire(pktsz, GFP_KERNEL);
|
||||||
if (!skb) {
|
if (!skb) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -448,7 +448,7 @@ bool tipc_msg_make_bundle(struct sk_buff **skb, struct tipc_msg *msg,
|
||||||
if (msz > (max / 2))
|
if (msz > (max / 2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_skb = tipc_buf_acquire(max);
|
_skb = tipc_buf_acquire(max, GFP_ATOMIC);
|
||||||
if (!_skb)
|
if (!_skb)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err)
|
||||||
|
|
||||||
/* Never return SHORT header; expand by replacing buffer if necessary */
|
/* Never return SHORT header; expand by replacing buffer if necessary */
|
||||||
if (msg_short(hdr)) {
|
if (msg_short(hdr)) {
|
||||||
*skb = tipc_buf_acquire(BASIC_H_SIZE + dlen);
|
*skb = tipc_buf_acquire(BASIC_H_SIZE + dlen, GFP_ATOMIC);
|
||||||
if (!*skb)
|
if (!*skb)
|
||||||
goto exit;
|
goto exit;
|
||||||
memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen);
|
memcpy((*skb)->data + BASIC_H_SIZE, msg_data(hdr), dlen);
|
||||||
|
|
|
@ -820,7 +820,7 @@ static inline bool msg_is_reset(struct tipc_msg *hdr)
|
||||||
return (msg_user(hdr) == LINK_PROTOCOL) && (msg_type(hdr) == RESET_MSG);
|
return (msg_user(hdr) == LINK_PROTOCOL) && (msg_type(hdr) == RESET_MSG);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sk_buff *tipc_buf_acquire(u32 size);
|
struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp);
|
||||||
bool tipc_msg_validate(struct sk_buff *skb);
|
bool tipc_msg_validate(struct sk_buff *skb);
|
||||||
bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
|
bool tipc_msg_reverse(u32 own_addr, struct sk_buff **skb, int err);
|
||||||
void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
|
void tipc_msg_init(u32 own_addr, struct tipc_msg *m, u32 user, u32 type,
|
||||||
|
|
|
@ -69,7 +69,7 @@ static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
|
||||||
u32 dest)
|
u32 dest)
|
||||||
{
|
{
|
||||||
struct tipc_net *tn = net_generic(net, tipc_net_id);
|
struct tipc_net *tn = net_generic(net, tipc_net_id);
|
||||||
struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size);
|
struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE + size, GFP_ATOMIC);
|
||||||
struct tipc_msg *msg;
|
struct tipc_msg *msg;
|
||||||
|
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
|
|
Loading…
Reference in New Issue