libceph: use memalloc flags for net IO
This patch has ceph's lib code use the memalloc flags. If the VM layer needs to write data out to free up memory to handle new allocation requests, the block layer must be able to make forward progress. To handle that requirement we use structs like mempools to reserve memory for objects like bios and requests. The problem is when we send/receive block layer requests over the network layer, net skb allocations can fail and the system can lock up. To solve this, the memalloc related flags were added. NBD, iSCSI and NFS uses these flags to tell the network/vm layer that it should use memory reserves to fullfill allcation requests for structs like skbs. I am running ceph in a bunch of VMs in my laptop, so this patch was not tested very harshly. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Reviewed-by: Ilya Dryomov <idryomov@redhat.com>
This commit is contained in:
parent
f5ee37bd31
commit
89baaa570a
|
@ -484,7 +484,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
|
||||||
IPPROTO_TCP, &sock);
|
IPPROTO_TCP, &sock);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
sock->sk->sk_allocation = GFP_NOFS;
|
sock->sk->sk_allocation = GFP_NOFS | __GFP_MEMALLOC;
|
||||||
|
|
||||||
#ifdef CONFIG_LOCKDEP
|
#ifdef CONFIG_LOCKDEP
|
||||||
lockdep_set_class(&sock->sk->sk_lock, &socket_class);
|
lockdep_set_class(&sock->sk->sk_lock, &socket_class);
|
||||||
|
@ -509,6 +509,9 @@ static int ceph_tcp_connect(struct ceph_connection *con)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sk_set_memalloc(sock->sk);
|
||||||
|
|
||||||
con->sock = sock;
|
con->sock = sock;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2769,8 +2772,11 @@ static void con_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct ceph_connection *con = container_of(work, struct ceph_connection,
|
struct ceph_connection *con = container_of(work, struct ceph_connection,
|
||||||
work.work);
|
work.work);
|
||||||
|
unsigned long pflags = current->flags;
|
||||||
bool fault;
|
bool fault;
|
||||||
|
|
||||||
|
current->flags |= PF_MEMALLOC;
|
||||||
|
|
||||||
mutex_lock(&con->mutex);
|
mutex_lock(&con->mutex);
|
||||||
while (true) {
|
while (true) {
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -2824,6 +2830,8 @@ static void con_work(struct work_struct *work)
|
||||||
con_fault_finish(con);
|
con_fault_finish(con);
|
||||||
|
|
||||||
con->ops->put(con);
|
con->ops->put(con);
|
||||||
|
|
||||||
|
tsk_restore_flags(current, pflags, PF_MEMALLOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue