Skip to content

Commit f572bf2

Browse files
Hakon-BuggeNipaLocal
authored andcommitted
rds: Brute force GFP_NOIO
For most entry points to RDS, we call memalloc_noio_{save,restore} in a parenthetic fashion when enabled by the module parameter force_noio. We skip the calls to memalloc_noio_{save,restore} in rds_ioctl(), as no memory allocations are executed in this function or its callees. The reason we execute memalloc_noio_{save,restore} in rds_poll(), is due to the following call chain: rds_poll() poll_wait() __pollwait() poll_get_entry() __get_free_page(GFP_KERNEL) The function rds_setsockopt() allocates memory in its callee's rds_get_mr() and rds_get_mr_for_dest(). Hence, we need memalloc_noio_{save,restore} in rds_setsockopt(). In rds_getsockopt(), we have rds_info_getsockopt() that allocates memory. Hence, we need memalloc_noio_{save,restore} in rds_getsockopt(). All the above, in order to conditionally enable RDS to become a block I/O device. Signed-off-by: Håkon Bugge <[email protected]> Signed-off-by: NipaLocal <nipa@local>
1 parent 4c0f78f commit f572bf2

File tree

1 file changed

+56
-3
lines changed

1 file changed

+56
-3
lines changed

net/rds/af_rds.c

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,15 @@
3737
#include <linux/in.h>
3838
#include <linux/ipv6.h>
3939
#include <linux/poll.h>
40+
#include <linux/sched/mm.h>
4041
#include <net/sock.h>
4142

4243
#include "rds.h"
4344

45+
static bool rds_force_noio;
46+
module_param_named(force_noio, rds_force_noio, bool, 0444);
47+
MODULE_PARM_DESC(force_noio, "Force the use of GFP_NOIO (Y/N)");
48+
4449
/* this is just used for stats gathering :/ */
4550
static DEFINE_SPINLOCK(rds_sock_lock);
4651
static unsigned long rds_sock_count;
@@ -59,8 +64,12 @@ DECLARE_WAIT_QUEUE_HEAD(rds_poll_waitq);
5964
static int rds_release(struct socket *sock)
6065
{
6166
struct sock *sk = sock->sk;
67+
unsigned int noio_flags;
6268
struct rds_sock *rs;
6369

70+
if (rds_force_noio)
71+
noio_flags = memalloc_noio_save();
72+
6473
if (!sk)
6574
goto out;
6675

@@ -90,6 +99,8 @@ static int rds_release(struct socket *sock)
9099
sock->sk = NULL;
91100
sock_put(sk);
92101
out:
102+
if (rds_force_noio)
103+
memalloc_noio_restore(noio_flags);
93104
return 0;
94105
}
95106

@@ -214,9 +225,13 @@ static __poll_t rds_poll(struct file *file, struct socket *sock,
214225
{
215226
struct sock *sk = sock->sk;
216227
struct rds_sock *rs = rds_sk_to_rs(sk);
228+
unsigned int noio_flags;
217229
__poll_t mask = 0;
218230
unsigned long flags;
219231

232+
if (rds_force_noio)
233+
noio_flags = memalloc_noio_save();
234+
220235
poll_wait(file, sk_sleep(sk), wait);
221236

222237
if (rs->rs_seen_congestion)
@@ -249,6 +264,8 @@ static __poll_t rds_poll(struct file *file, struct socket *sock,
249264
if (mask)
250265
rs->rs_seen_congestion = 0;
251266

267+
if (rds_force_noio)
268+
memalloc_noio_restore(noio_flags);
252269
return mask;
253270
}
254271

@@ -293,9 +310,13 @@ static int rds_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
293310
static int rds_cancel_sent_to(struct rds_sock *rs, sockptr_t optval, int len)
294311
{
295312
struct sockaddr_in6 sin6;
313+
unsigned int noio_flags;
296314
struct sockaddr_in sin;
297315
int ret = 0;
298316

317+
if (rds_force_noio)
318+
noio_flags = memalloc_noio_save();
319+
299320
/* racing with another thread binding seems ok here */
300321
if (ipv6_addr_any(&rs->rs_bound_addr)) {
301322
ret = -ENOTCONN; /* XXX not a great errno */
@@ -324,6 +345,8 @@ static int rds_cancel_sent_to(struct rds_sock *rs, sockptr_t optval, int len)
324345

325346
rds_send_drop_to(rs, &sin6);
326347
out:
348+
if (rds_force_noio)
349+
memalloc_noio_restore(noio_flags);
327350
return ret;
328351
}
329352

@@ -485,8 +508,12 @@ static int rds_getsockopt(struct socket *sock, int level, int optname,
485508
{
486509
struct rds_sock *rs = rds_sk_to_rs(sock->sk);
487510
int ret = -ENOPROTOOPT, len;
511+
unsigned int noio_flags;
488512
int trans;
489513

514+
if (rds_force_noio)
515+
noio_flags = memalloc_noio_save();
516+
490517
if (level != SOL_RDS)
491518
goto out;
492519

@@ -529,6 +556,8 @@ static int rds_getsockopt(struct socket *sock, int level, int optname,
529556
}
530557

531558
out:
559+
if (rds_force_noio)
560+
memalloc_noio_restore(noio_flags);
532561
return ret;
533562

534563
}
@@ -538,12 +567,16 @@ static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
538567
{
539568
struct sock *sk = sock->sk;
540569
struct sockaddr_in *sin;
570+
unsigned int noio_flags;
541571
struct rds_sock *rs = rds_sk_to_rs(sk);
542572
int ret = 0;
543573

544574
if (addr_len < offsetofend(struct sockaddr, sa_family))
545575
return -EINVAL;
546576

577+
if (rds_force_noio)
578+
noio_flags = memalloc_noio_save();
579+
547580
lock_sock(sk);
548581

549582
switch (uaddr->sa_family) {
@@ -626,6 +659,8 @@ static int rds_connect(struct socket *sock, struct sockaddr *uaddr,
626659
}
627660

628661
release_sock(sk);
662+
if (rds_force_noio)
663+
memalloc_noio_restore(noio_flags);
629664
return ret;
630665
}
631666

@@ -697,16 +732,28 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
697732
static int rds_create(struct net *net, struct socket *sock, int protocol,
698733
int kern)
699734
{
735+
unsigned int noio_flags;
700736
struct sock *sk;
737+
int ret;
701738

702739
if (sock->type != SOCK_SEQPACKET || protocol)
703740
return -ESOCKTNOSUPPORT;
704741

742+
if (rds_force_noio)
743+
noio_flags = memalloc_noio_save();
744+
705745
sk = sk_alloc(net, AF_RDS, GFP_KERNEL, &rds_proto, kern);
706-
if (!sk)
707-
return -ENOMEM;
746+
if (!sk) {
747+
ret = -ENOMEM;
748+
goto out;
749+
}
708750

709-
return __rds_create(sock, sk, protocol);
751+
ret = __rds_create(sock, sk, protocol);
752+
out:
753+
if (rds_force_noio)
754+
memalloc_noio_restore(noio_flags);
755+
756+
return ret;
710757
}
711758

712759
void rds_sock_addref(struct rds_sock *rs)
@@ -895,8 +942,12 @@ u32 rds_gen_num;
895942

896943
static int __init rds_init(void)
897944
{
945+
unsigned int noio_flags;
898946
int ret;
899947

948+
if (rds_force_noio)
949+
noio_flags = memalloc_noio_save();
950+
900951
net_get_random_once(&rds_gen_num, sizeof(rds_gen_num));
901952

902953
ret = rds_bind_lock_init();
@@ -947,6 +998,8 @@ static int __init rds_init(void)
947998
out_bind:
948999
rds_bind_lock_destroy();
9491000
out:
1001+
if (rds_force_noio)
1002+
memalloc_noio_restore(noio_flags);
9501003
return ret;
9511004
}
9521005
module_init(rds_init);

0 commit comments

Comments
 (0)