Closed Bug 1362822 Opened 7 years ago Closed 7 years ago

Unnecessary locking cost during the creation of HTTP channels

Categories

(Core :: Networking: HTTP, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla55
Tracking Status
firefox55 --- fixed

People

(Reporter: ehsan.akhgari, Assigned: ehsan.akhgari)

References

Details

(Whiteboard: [necko-active])

Attachments

(2 files)

See this perf profile:

   - 5.65% imgLoader::LoadImage                                                                       ▒
      + 3.06% mozilla::net::HttpChannelChild::AsyncOpen2                                              ▒
      - 1.50% NewImageChannel                                                                         ▒
         - 0.96% NS_NewChannelWithTriggeringPrincipal                                                 ▒
              NS_NewChannelInternal                                                                   ▒
              mozilla::net::nsIOService::NewChannelFromURI2                                           ▒
            - mozilla::net::nsIOService::NewChannelFromURIWithProxyFlags2                             ▒
               - 0.43% mozilla::net::nsIOService::NewChannelFromURIWithProxyFlagsInternal             ◆
                  - mozilla::net::nsHttpHandler::NewProxiedChannel2                                   ▒
                     - 0.14% mozilla::net::HttpBaseChannel::Init                                      ▒
                        - 0.07% mozilla::net::nsHttpHandler::AddStandardRequestHeaders                ▒
                             0.05% pthread_mutex_unlock                                               ▒
                           - 0.02% mozilla::net::nsHttpRequestHead::SetHeader                         ▒
                                mozilla::net::nsHttpHeaderArray::SetHeader_internal                   ▒
                                nsTArray_Impl<mozilla::net::nsHttpHeaderArray::nsEntry, nsTArrayInfall▒
                                nsTArray_base<nsTArrayInfallibleAllocator, nsTArray_CopyWithMemutils>:▒
                                moz_xrealloc                                                          ▒
                                pthread_mutex_unlock                                                  ▒

A lot of the cost of HttpBaseChannel::Init() is coming from the locking cost from the SetHeader calls under nsHttpHandler::AddStandardRequestHeaders().  This is quite silly because we are just creating the channel object, and there is yet no other consumer to protect against.
The channel objects cannot be handed off to other threads before the creation
process has been finished, so there is no point in trying to hold these locks
while the initialization code is running.  These lockings have shown up in
profiles as being expensive.
Attachment #8865180 - Flags: review?(schien)
Comment on attachment 8865180 [details] [diff] [review]
Avoid needlessly holding locks when setting headers during the initialization of HTTP channel objects

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

Another way to do it is to call |nsHttpHeaderArray::SetHeader| directly.
We can either use the nsHttpRequestHead::Headers to modify the header array in place, or write into a local nsHttpHeaderArray then replace the one in nsHttpRequestHead.

@macmanus, which approach you prefer? create non-thread-safe function in nsHttpRequestHead or modify nsHttpHeaderArray directly.

::: netwerk/protocol/http/nsHttpRequestHead.h
@@ +114,5 @@
> +    // This function is designed to only be called during the
> +    // creation of this object, and doesn't grab the lock of the
> +    // object before setting the header.  Please do not use it if
> +    // you are not sure why you need it.
> +    MOZ_MUST_USE nsresult SetHeaderNonThreadSafe(nsHttpAtom h,

I'd like to name it |InitHeaderNonThreadSafe| to explicitly state the usage in initialization phase.
Attachment #8865180 - Flags: feedback?(mcmanus)
Attachment #8865180 - Flags: review?(dd.mozilla)
Attachment #8865180 - Flags: feedback?(mcmanus)
Attachment #8865180 - Flags: feedback?(dd.mozilla)
dragana is the expert here - she should decide
Comment on attachment 8865180 [details] [diff] [review]
Avoid needlessly holding locks when setting headers during the initialization of HTTP channel objects

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

::: netwerk/protocol/http/nsHttpHandler.cpp
@@ +529,5 @@
>      return rv;
>  }
>  
>  nsresult
>  nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecure)

Can you please add a scary comment (that says that headers are not lock and that it is allowed to use this function only in HttpBaseChannel::init) above declaration of this function as well. I am afraid that someone will decide to use this function outside of nsHttpChannel::Init.
Attachment #8865180 - Flags: review?(dd.mozilla)
Attachment #8865180 - Flags: review+
Attachment #8865180 - Flags: feedback?(dd.mozilla)
Attachment #8865180 - Flags: feedback+
Should there be a debug flag on nsHttpRequestHead we drop at the end of HttpBaseChannel::init to have a nice assert in SetHeaderNonThreadSafe?
Comment on attachment 8865180 [details] [diff] [review]
Avoid needlessly holding locks when setting headers during the initialization of HTTP channel objects

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

r+'ed with @dragana's comment addressed.
Attachment #8865180 - Flags: review?(schien) → review+
I will add the comments, but I think Honza is right, an assertion would be much better!  I'll add one.
I think this got complex enough to merit a review of its own.  I'm planning to fold this into the previous patch when landing, so apologies for the messy commit message and the diff, but this is the changes that I made on top of what you reviewed previously, so that you don't have to spend time looking over the same changes twice!

(If you prefer the assertion part to be landed as a separate patch please let me know, I can move the added comment to the previous part...)
Attachment #8866596 - Flags: review?(dd.mozilla)
Comment on attachment 8866596 [details] [diff] [review]
follow-up: Address the review comments and add the suggested assertion

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

Thank you!
Attachment #8866596 - Flags: review?(dd.mozilla) → review+
Pushed by eakhgari@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/0a25a0fa3b32
Avoid needlessly holding locks when setting headers during the initialization of HTTP channel objects; r=schien,dragana
Whiteboard: [necko-active]
Hmm, that was probably bug 1363893. I'll get this relanded later today.
Keywords: checkin-needed
Pushed by ryanvm@gmail.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/35f21a51a75b
Avoid needlessly holding locks when setting headers during the initialization of HTTP channel objects; r=schien,dragana
Keywords: checkin-needed
Backout by kwierso@gmail.com:
https://hg.mozilla.org/mozilla-central/rev/2a8e0c4be57d
Backed out changeset 0a25a0fa3b32 for osx debug devtools timeouts a=merge
Flags: needinfo?(ehsan)
https://hg.mozilla.org/mozilla-central/rev/35f21a51a75b
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla55
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: