Closed Bug 806992 Opened 12 years ago Closed 12 years ago

EV initialization blocks the first certificate verification thread for a long time

Categories

(Core :: Security: PSM, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla20

People

(Reporter: briansmith, Assigned: mcmanus)

Details

(Keywords: perf)

Attachments

(1 file, 2 obsolete files)

According to mcmanus, initialization of the EV--nsNSSComponent::IdentityInfoInit()--blocks the first certificate validation by ~30ms.

Patrick, please confirm.
(In reply to Brian Smith (:bsmith) from comment #0)
> According to mcmanus, initialization of the
> EV--nsNSSComponent::IdentityInfoInit()--blocks the first certificate
> validation by ~30ms.
> 
> Patrick, please confirm.

ack.

more like 20ms in my opt build, but still a lot. (core i7)
Attached patch patch 0 (obsolete) — Splinter Review
you may want a different patch, but in the spirit of writing code instead of bugzilla comments I have been using this one for the last hour with good results for the false start work (i.e. calling handshakecallback out of AuthCertificateComplete instead of sendClientSecondRound is adding about 1ms of delay instead of 20-30).

It adds a one-time hook when starting a TLS connection to ensure the EV.init is done (and does it on a server cert verification thread, so it doesn't block the connection logic). The effectively overlaps the SSL round trip with the EV.init

NSS itself seems lazily init'd - trying the same logic out of the socket transport init routine before that happens triggers the nss init, which was a pretty unhappy thing off the main thread. Likewise, making it synchronous back on the main thread during startup looked like it was undoing some work that was intentionally done to speed startup.

So lazy makes some sense, but doing it in parallel with a connect should get us the best of both worlds unless you've got a top 5% network.
Attachment #676701 - Flags: review?(bsmith)
Attached patch patch 1 (obsolete) — Splinter Review
The android compiler objected to how I defined a class inside a function and passed a RefPtr to it outside..

the patch update just moves the class a few lines up.
Attachment #676701 - Attachment is obsolete: true
Attachment #676701 - Flags: review?(bsmith)
Attachment #681776 - Flags: review?(bsmith)
Comment on attachment 681776 [details] [diff] [review]
patch 1

Review of attachment 681776 [details] [diff] [review]:
-----------------------------------------------------------------

::: security/manager/ssl/src/SSLServerCertVerification.cpp
@@ +1217,5 @@
> +private:
> +  NS_IMETHOD Run()
> +  {
> +    nsresult rv;
> +    nsCOMPtr<nsINSSComponent> inss = do_GetService(PSM_COMPONENT_CONTRACTID, &rv);

You need to prevent NSS from shutting down and you need to check that NSS hasn't already shut down. The easiest way to do this is to use the CryptoTask helper class from bug 804663.

::: security/manager/ssl/src/nsNSSIOLayer.cpp
@@ +2358,5 @@
>    }
> +
> +  // This is an optimization to make sure the identity info dataset is
> +  // parsed on a seaparte thread and can be overlapped with network latency.
> +  EnsureServerVerificationInitialized();

The initialization of the EV info will race against all the actual validations that depend on it, right? It seems like the patch is written on the assumption that all validations are serialized, but actually the serializations are done on a 5-thread thread pool.
Attachment #681776 - Flags: review?(bsmith) → review-
I think that this can be resolved by moving this runtime initialization to build time, or by (re)moving the unnecessary work that the EV identity info initialization is doing. AFAICT, at most it should only need to register OIDs, but instead it is reading certificates out of the cert DB (off disk) for reasons that are unclear to me (so, perhaps unnecessarily).
(In reply to Brian Smith (:bsmith) from comment #4)

> 
> You need to prevent NSS from shutting down and you need to check that NSS
> hasn't already shut down. The easiest way to do this is to use the
> CryptoTask helper class from bug 804663.

thanks.. I'll skip the dep on 804663 and do it the old school way.

> 
> ::: security/manager/ssl/src/nsNSSIOLayer.cpp
> @@ +2358,5 @@
> >    }
> > +
> > +  // This is an optimization to make sure the identity info dataset is
> > +  // parsed on a seaparte thread and can be overlapped with network latency.
> > +  EnsureServerVerificationInitialized();
> 
> The initialization of the EV info will race against all the actual
> validations that depend on it, right? It seems like the patch is written on
> the assumption that all validations are serialized, but actually the
> serializations are done on a 5-thread thread pool.

I don't believe serialization is assumed - and I think this is ok because in the end it boils down to triggering 1 early call of EnsureIdentityInfoLoaded() on a cert verification thread so that the loading can happen while the pre certificate exchanges are going on. All cert verifications also end up calling EnsureIdentityInfoLoaded just like they used to in case they are ready for verification before the identity info loading is complete.

http://mxr.mozilla.org/mozilla-central/source/security/manager/ssl/src/nsIdentityChecking.cpp#1319

EnsureIdentityInfoLoaded() uses PR_CallOnce to drive the actual initialization through IdentityInfoInit.. CallOnce() guarantees both that IdentityInfoInit is only called once and that any 'extra' threads racing against that first execution all wait until IdentityInfoInit() has finished executing (so they can't proceed with incomplete initialization). Indeed nothing has really changed here wrt parallelism, I've just tossed one more EnsureIdentityInfo() into the mix.

The common case of CallOnce (i.e. post initialization) is really cheap - an unlocked comparison.

http://mxr.mozilla.org/mozilla-central/source/nsprpub/pr/src/misc/prinit.c#773

So I think we're on solid footing there.
Attached patch patch 2Splinter Review
let's see how I did with the nsNSSShutDown incantation
Attachment #681776 - Attachment is obsolete: true
Attachment #682169 - Flags: review?(bsmith)
Attachment #682169 - Flags: review?(bsmith) → review+
Comment on attachment 682169 [details] [diff] [review]
patch 2

double reviews! (I think I want r? here ... if I want sr? then by all means do that :))
Attachment #682169 - Flags: review?(honzab.moz)
Comment on attachment 682169 [details] [diff] [review]
patch 2

Review of attachment 682169 [details] [diff] [review]:
-----------------------------------------------------------------

r=honzab

::: security/manager/ssl/src/SSLServerCertVerification.cpp
@@ +1223,5 @@
> +    if (isAlreadyShutDown())
> +      return NS_OK;
> +
> +    nsresult rv;
> +    nsCOMPtr<nsINSSComponent> inss = do_GetService(PSM_COMPONENT_CONTRACTID, &rv);

If PSM_COMPONENT has already been instantiated on the main thread, then this is OK.  I believe it has been.
Attachment #682169 - Flags: review?(honzab.moz) → review+
https://hg.mozilla.org/mozilla-central/rev/b2cc2d9da6be
Assignee: nobody → mcmanus
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla20
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: