diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d6e94cc8066c..c4f0a65aac0e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5250,6 +5250,18 @@ unsigned long __alloc_pages_bulk(gfp_t gfp, int preferred_nid, if (nr_pages - nr_populated == 1) goto failed; +#ifdef CONFIG_PAGE_OWNER + /* + * PAGE_OWNER may recurse into the allocator to allocate space to + * save the stack with pagesets.lock held. Releasing/reacquiring + * removes much of the performance benefit of bulk allocation so + * force the caller to allocate one page at a time as it'll have + * similar performance to added complexity to the bulk allocator. + */ + if (static_branch_unlikely(&page_owner_inited)) + goto failed; +#endif + /* May set ALLOC_NOFRAGMENT, fragmentation will return 1 page. */ gfp &= gfp_allowed_mask; alloc_gfp = gfp; diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index fd69a03d6137a..ad78bf631900b 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -156,12 +156,11 @@ static void virtscsi_complete_cmd(struct virtio_scsi *vscsi, void *buf) WARN_ON(virtio32_to_cpu(vscsi->vdev, resp->sense_len) > VIRTIO_SCSI_SENSE_SIZE); - if (sc->sense_buffer) { + if (resp->sense_len) { memcpy(sc->sense_buffer, resp->sense, min_t(u32, virtio32_to_cpu(vscsi->vdev, resp->sense_len), VIRTIO_SCSI_SENSE_SIZE)); - set_status_byte(sc, SAM_STAT_CHECK_CONDITION); } sc->scsi_done(sc); diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index b04a5a02ecf3..d8e1ac1ae10d 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -758,20 +758,46 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event) if (event == HCI_DEV_UNREG) { struct sock *sk; + bool put_dev; +restart: + put_dev = false; /* Detach sockets from device */ read_lock(&hci_sk_list.lock); sk_for_each(sk, &hci_sk_list.head) { + /* hci_sk_list.lock is preventing hci_sock_release() + * from calling bt_sock_unlink(). + */ + if (hci_pi(sk)->hdev != hdev || sk_unhashed(sk)) + continue; + /* Take a ref because we can't call lock_sock() with + * hci_sk_list.lock held. + */ + sock_hold(sk); + read_unlock(&hci_sk_list.lock); lock_sock(sk); - if (hci_pi(sk)->hdev == hdev) { + /* Since hci_sock_release() might have already called + * bt_sock_unlink() while waiting for lock_sock(), + * use sk_hashed(sk) for checking that bt_sock_unlink() + * is not yet called. + */ + write_lock(&hci_sk_list.lock); + if (sk_hashed(sk) && hci_pi(sk)->hdev == hdev) { hci_pi(sk)->hdev = NULL; sk->sk_err = EPIPE; sk->sk_state = BT_OPEN; sk->sk_state_change(sk); - - hci_dev_put(hdev); + put_dev = true; } + write_unlock(&hci_sk_list.lock); release_sock(sk); + sock_put(sk); + if (put_dev) + hci_dev_put(hdev); + /* Restarting is safe, for hci_pi(sk)->hdev != hdev if + * condition met and sk_unhashed(sk) == true otherwise. + */ + goto restart; } read_unlock(&hci_sk_list.lock); }