Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

um: net: replace GFP_KERNEL with GFP_ATOMIC when spinlock is held

since GFP_KERNEL with GFP_ATOMIC while spinlock is held,
as code while holding a spinlock should be atomic.
GFP_KERNEL may sleep and can cause deadlock,
where as GFP_ATOMIC may fail but certainly avoids deadlockdex f70dd54..d898f6c 100644

Signed-off-by: Saurabh Sengar <saurabh.truth@gmail.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

Saurabh Sengar and committed by
Richard Weinberger
e17c6d77 70c8205f

+9 -8
+9 -8
arch/um/drivers/net_kern.c
··· 388 388 static int driver_registered; 389 389 390 390 static void eth_configure(int n, void *init, char *mac, 391 - struct transport *transport) 391 + struct transport *transport, gfp_t gfp_mask) 392 392 { 393 393 struct uml_net *device; 394 394 struct net_device *dev; ··· 397 397 398 398 size = transport->private_size + sizeof(struct uml_net_private); 399 399 400 - device = kzalloc(sizeof(*device), GFP_KERNEL); 400 + device = kzalloc(sizeof(*device), gfp_mask); 401 401 if (device == NULL) { 402 402 printk(KERN_ERR "eth_configure failed to allocate struct " 403 403 "uml_net\n"); ··· 568 568 static LIST_HEAD(eth_cmd_line); 569 569 570 570 static int check_transport(struct transport *transport, char *eth, int n, 571 - void **init_out, char **mac_out) 571 + void **init_out, char **mac_out, gfp_t gfp_mask) 572 572 { 573 573 int len; 574 574 ··· 582 582 else if (*eth != '\0') 583 583 return 0; 584 584 585 - *init_out = kmalloc(transport->setup_size, GFP_KERNEL); 585 + *init_out = kmalloc(transport->setup_size, gfp_mask); 586 586 if (*init_out == NULL) 587 587 return 1; 588 588 ··· 609 609 list_for_each_safe(ele, next, &eth_cmd_line) { 610 610 eth = list_entry(ele, struct eth_init, list); 611 611 match = check_transport(new, eth->init, eth->index, &init, 612 - &mac); 612 + &mac, GFP_KERNEL); 613 613 if (!match) 614 614 continue; 615 615 else if (init != NULL) { 616 - eth_configure(eth->index, init, mac, new); 616 + eth_configure(eth->index, init, mac, new, GFP_KERNEL); 617 617 kfree(init); 618 618 } 619 619 list_del(&eth->list); ··· 631 631 spin_lock(&transports_lock); 632 632 list_for_each(ele, &transports) { 633 633 transport = list_entry(ele, struct transport, list); 634 - if (!check_transport(transport, str, index, &init, &mac)) 634 + if (!check_transport(transport, str, index, &init, 635 + &mac, GFP_ATOMIC)) 635 636 continue; 636 637 if (init != NULL) { 637 - eth_configure(index, init, mac, transport); 638 + eth_configure(index, init, mac, transport, GFP_ATOMIC); 638 639 kfree(init); 639 640 } 640 641 found = 1;