diff options
| author | Mohit Khanna <mkhannaqca@codeaurora.org> | 2016-11-16 20:22:03 -0800 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2016-12-07 18:39:35 -0800 |
| commit | 3b4c4bb6194190b355155e393011fc504aee994f (patch) | |
| tree | 2dd8f7e270a00862b9b913e9369f321b17f00f7b | |
| parent | 4a99f59c5cc402ea71f01cfde27fa0c124888099 (diff) | |
qcacld-3.0: Make interrupt blacklisting robust
Interrupt blacklisting in kernel 4.4 happens through a user-space
entity. The kernel APIs irq_blacklist_on(off) essentially send
a message to the user space service(irq balancer) and
therefore are not synchronous and do not guarantee that blacklisting
has actually taken effect. It will be granted with some latency
(userspace entity's processing delay).
Make blacklisting more robust by:
a) move irq (if it has been moved around after blacklist_on call
has been made and not yet honored) to the designated CPU
on IRQ reception
b) stop cpu_isolation in blacklisting mode boost API
c) modify NAPI stats to indicate blacklisting mode
CRs-Fixed: 1093770
Change-Id: I410768d3e0215e510924859d678c66ad7d87b1ec
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 11 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 46 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_napi.c | 17 |
3 files changed, 42 insertions, 32 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 48095e422e44..b3ef6da558e0 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -340,8 +340,6 @@ extern spinlock_t hdd_context_lock; * received over 100ms intervals * @interval_rx: # of rx packets received in the last 100ms interval * @interval_tx: # of tx packets received in the last 100ms interval - * @total_rx: # of total rx packets received on interface - * @total_tx: # of total tx packets received on interface * @next_vote_level: pld_bus_width_type voting level (high or low) * determined on the basis of total tx and rx packets * received in the last 100ms interval @@ -351,18 +349,19 @@ extern spinlock_t hdd_context_lock; * @next_tx_level: pld_bus_width_type voting level (high or low) * determined on the basis of tx packets received in the * last 100ms interval + * @qtime timestamp when the record is added * - * The structure keeps track of throughput requirements of wlan driver in 100ms - * intervals for later analysis. + * The structure keeps track of throughput requirements of wlan driver. + * An entry is added if either of next_vote_level, next_rx_level or + * next_tx_level changes. An entry is not added for every 100ms interval. */ struct hdd_tx_rx_histogram { uint64_t interval_rx; uint64_t interval_tx; - uint64_t total_rx; - uint64_t total_tx; uint32_t next_vote_level; uint32_t next_rx_level; uint32_t next_tx_level; + uint64_t qtime; }; typedef struct hdd_tx_rx_stats_s { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 71458d9ba2e0..a8a525cce361 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -5281,6 +5281,10 @@ static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx, enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE; enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE; uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count; + uint16_t index = 0; + bool vote_level_change = false; + bool rx_level_change = false; + bool tx_level_change = false; if (total > hdd_ctx->config->busBandwidthHighThreshold) next_vote_level = PLD_BUS_WIDTH_HIGH; @@ -5291,13 +5295,11 @@ static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx, else next_vote_level = PLD_BUS_WIDTH_NONE; - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_vote_level = - next_vote_level; - if (hdd_ctx->cur_vote_level != next_vote_level) { hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld", next_vote_level, tx_packets, rx_packets); hdd_ctx->cur_vote_level = next_vote_level; + vote_level_change = true; pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level); if (next_vote_level == PLD_BUS_WIDTH_LOW) { if (hdd_ctx->hbw_requested) { @@ -5332,13 +5334,11 @@ static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx, hdd_ctx->rx_high_ind_cnt = 0; } - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_rx_level = - next_rx_level; - if (hdd_ctx->cur_rx_level != next_rx_level) { hdd_debug("TCP DELACK trigger level %d, average_rx: %llu", next_rx_level, temp_rx); hdd_ctx->cur_rx_level = next_rx_level; + rx_level_change = true; /* Send throughput indication only if it is enabled. * Disabling tcp_del_ack will revert the tcp stack behavior * to default delayed ack. Note that this will disable the @@ -5363,16 +5363,25 @@ static void hdd_pld_request_bus_bandwidth(hdd_context_t *hdd_ctx, hdd_debug("change TCP TX trigger level %d, average_tx: %llu", next_tx_level, temp_tx); hdd_ctx->cur_tx_level = next_tx_level; + tx_level_change = true; wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index, WLAN_SVC_WLAN_TP_TX_IND, &next_tx_level, sizeof(next_tx_level)); } - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].next_tx_level = - next_tx_level; - hdd_ctx->hdd_txrx_hist_idx++; - hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK; + index = hdd_ctx->hdd_txrx_hist_idx; + + if (vote_level_change || tx_level_change || rx_level_change) { + hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level; + hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level; + hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level; + hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets; + hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets; + hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp(); + hdd_ctx->hdd_txrx_hist_idx++; + hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK; + } } #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1) @@ -5457,13 +5466,6 @@ static void hdd_bus_bw_compute_cbk(void *priv) connected = true; } - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].total_rx = total_rx; - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].total_tx = total_tx; - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].interval_rx = - rx_packets; - hdd_ctx->hdd_txrx_hist[hdd_ctx->hdd_txrx_hist_idx].interval_tx = - tx_packets; - /* add intra bss forwarded tx and rx packets */ tx_packets += fwd_tx_packets_diff; rx_packets += fwd_rx_packets_diff; @@ -5585,17 +5587,15 @@ void wlan_hdd_display_tx_rx_histogram(hdd_context_t *hdd_ctx) hdd_err("Total entries: %d Current index: %d", NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx); - hdd_err("index, total_rx, interval_rx, total_tx, interval_tx, bus_bw_level, RX TP Level, TX TP Level"); + hdd_err("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level"); for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) { /* using hdd_log to avoid printing function name */ - if (hdd_ctx->hdd_txrx_hist[i].total_rx != 0 || - hdd_ctx->hdd_txrx_hist[i].total_tx != 0) + if (hdd_ctx->hdd_txrx_hist[i].qtime > 0) hdd_log(QDF_TRACE_LEVEL_ERROR, - "%d: %llu, %llu, %llu, %llu, %s, %s, %s", - i, hdd_ctx->hdd_txrx_hist[i].total_rx, + "[%3d][%15llu]: %6llu, %6llu, %s, %s, %s", + i, hdd_ctx->hdd_txrx_hist[i].qtime, hdd_ctx->hdd_txrx_hist[i].interval_rx, - hdd_ctx->hdd_txrx_hist[i].total_tx, hdd_ctx->hdd_txrx_hist[i].interval_tx, convert_level_to_string( hdd_ctx->hdd_txrx_hist[i]. diff --git a/core/hdd/src/wlan_hdd_napi.c b/core/hdd/src/wlan_hdd_napi.c index 3e79d995bccb..73f0136ca67d 100644 --- a/core/hdd/src/wlan_hdd_napi.c +++ b/core/hdd/src/wlan_hdd_napi.c @@ -106,6 +106,7 @@ int hdd_napi_create(void) struct hif_opaque_softc *hif_ctx; int rc = 0; hdd_context_t *hdd_ctx; + uint8_t feature_flags = 0; NAPI_DEBUG("-->"); @@ -114,9 +115,15 @@ int hdd_napi_create(void) QDF_ASSERT(NULL != hif_ctx); rc = -EFAULT; } else { + + feature_flags = QCA_NAPI_FEATURE_CPU_CORRECTION | + QCA_NAPI_FEATURE_IRQ_BLACKLISTING | + QCA_NAPI_FEATURE_CORE_CTL_BOOST; + rc = hif_napi_create(hif_ctx, hdd_napi_poll, QCA_NAPI_BUDGET, - QCA_NAPI_DEF_SCALE); + QCA_NAPI_DEF_SCALE, + feature_flags); if (rc < 0) { hdd_err("ERR(%d) creating NAPI instances", rc); @@ -395,7 +402,10 @@ int hdd_display_napi_stats(void) hdd_err("%s unable to retrieve napi structure", __func__); return -EFAULT; } - qdf_print("[NAPI -- STATS]: scheds polls comps done time-lim pkt-lim napi-buckets(%d)", QCA_NAPI_NUM_BUCKETS); + qdf_print("[NAPI %u][BL %d]: scheds polls comps done t-lim p-lim corr napi-buckets(%d)", + napid->napi_mode, + hif_napi_cpu_blacklist(napid->flags, BLACKLIST_QUERY), + QCA_NAPI_NUM_BUCKETS); for (i = 0; i < CE_COUNT_MAX; i++) if (napid->ce_map & (0x01 << i)) { @@ -412,7 +422,7 @@ int hdd_display_napi_stats(void) } if (napis->napi_schedules != 0) - qdf_print("NAPI[%2d]CPU[%2d]: %7d %7d %7d %7d %8d %7d %s", + qdf_print("NAPI[%2d]CPU[%d]: %7d %7d %7d %7d %5d %5d %5d %s", i, j, napis->napi_schedules, napis->napi_polls, @@ -420,6 +430,7 @@ int hdd_display_napi_stats(void) napis->napi_workdone, napis->time_limit_reached, napis->rxpkt_thresh_reached, + napis->cpu_corrected, buf); } } |
