Skip to content

Commit 571ed1f

Browse files
author
Trond Myklebust
committed
SUNRPC: Replace krb5_seq_lock with a lockless scheme
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent 0c1c19f commit 571ed1f

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed

include/linux/sunrpc/gss_krb5.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ struct krb5_ctx {
118118
u8 acceptor_integ[GSS_KRB5_MAX_KEYLEN];
119119
};
120120

121-
extern spinlock_t krb5_seq_lock;
121+
extern u32 gss_seq_send_fetch_and_inc(struct krb5_ctx *ctx);
122+
extern u64 gss_seq_send64_fetch_and_inc(struct krb5_ctx *ctx);
122123

123124
/* The length of the Kerberos GSS token header */
124125
#define GSS_KRB5_TOK_HDR_LEN (16)

net/sunrpc/auth_gss/gss_krb5_seal.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@
6868
# define RPCDBG_FACILITY RPCDBG_AUTH
6969
#endif
7070

71-
DEFINE_SPINLOCK(krb5_seq_lock);
72-
7371
static void *
7472
setup_token(struct krb5_ctx *ctx, struct xdr_netobj *token)
7573
{
@@ -124,6 +122,30 @@ setup_token_v2(struct krb5_ctx *ctx, struct xdr_netobj *token)
124122
return krb5_hdr;
125123
}
126124

125+
u32
126+
gss_seq_send_fetch_and_inc(struct krb5_ctx *ctx)
127+
{
128+
u32 old, seq_send = READ_ONCE(ctx->seq_send);
129+
130+
do {
131+
old = seq_send;
132+
seq_send = cmpxchg(&ctx->seq_send, old, old + 1);
133+
} while (old != seq_send);
134+
return seq_send;
135+
}
136+
137+
u64
138+
gss_seq_send64_fetch_and_inc(struct krb5_ctx *ctx)
139+
{
140+
u64 old, seq_send = READ_ONCE(ctx->seq_send);
141+
142+
do {
143+
old = seq_send;
144+
seq_send = cmpxchg(&ctx->seq_send64, old, old + 1);
145+
} while (old != seq_send);
146+
return seq_send;
147+
}
148+
127149
static u32
128150
gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
129151
struct xdr_netobj *token)
@@ -154,9 +176,7 @@ gss_get_mic_v1(struct krb5_ctx *ctx, struct xdr_buf *text,
154176

155177
memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
156178

157-
spin_lock(&krb5_seq_lock);
158-
seq_send = ctx->seq_send++;
159-
spin_unlock(&krb5_seq_lock);
179+
seq_send = gss_seq_send_fetch_and_inc(ctx);
160180

161181
if (krb5_make_seq_num(ctx, ctx->seq, ctx->initiate ? 0 : 0xff,
162182
seq_send, ptr + GSS_KRB5_TOK_HDR_LEN, ptr + 8))
@@ -174,7 +194,6 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
174194
.data = cksumdata};
175195
void *krb5_hdr;
176196
s32 now;
177-
u64 seq_send;
178197
u8 *cksumkey;
179198
unsigned int cksum_usage;
180199
__be64 seq_send_be64;
@@ -185,11 +204,7 @@ gss_get_mic_v2(struct krb5_ctx *ctx, struct xdr_buf *text,
185204

186205
/* Set up the sequence number. Now 64-bits in clear
187206
* text and w/o direction indicator */
188-
spin_lock(&krb5_seq_lock);
189-
seq_send = ctx->seq_send64++;
190-
spin_unlock(&krb5_seq_lock);
191-
192-
seq_send_be64 = cpu_to_be64(seq_send);
207+
seq_send_be64 = cpu_to_be64(gss_seq_send64_fetch_and_inc(ctx));
193208
memcpy(krb5_hdr + 8, (char *) &seq_send_be64, 8);
194209

195210
if (ctx->initiate) {

net/sunrpc/auth_gss/gss_krb5_wrap.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,7 @@ gss_wrap_kerberos_v1(struct krb5_ctx *kctx, int offset,
228228

229229
memcpy(ptr + GSS_KRB5_TOK_HDR_LEN, md5cksum.data, md5cksum.len);
230230

231-
spin_lock(&krb5_seq_lock);
232-
seq_send = kctx->seq_send++;
233-
spin_unlock(&krb5_seq_lock);
231+
seq_send = gss_seq_send_fetch_and_inc(kctx);
234232

235233
/* XXX would probably be more efficient to compute checksum
236234
* and encrypt at the same time: */
@@ -477,9 +475,7 @@ gss_wrap_kerberos_v2(struct krb5_ctx *kctx, u32 offset,
477475
*be16ptr++ = 0;
478476

479477
be64ptr = (__be64 *)be16ptr;
480-
spin_lock(&krb5_seq_lock);
481-
*be64ptr = cpu_to_be64(kctx->seq_send64++);
482-
spin_unlock(&krb5_seq_lock);
478+
*be64ptr = cpu_to_be64(gss_seq_send64_fetch_and_inc(kctx));
483479

484480
err = (*kctx->gk5e->encrypt_v2)(kctx, offset, buf, pages);
485481
if (err)

0 commit comments

Comments
 (0)